40歲開始學Java:Java中單例模式(Singleton Pattern),適用場景有哪些?

在這里插入圖片描述

在Java中,單例模式(Singleton Pattern)用于確保一個類只有一個實例,并提供全局訪問點。以下是詳細的實現方式、適用場景及注意事項:


一、單例模式的實現方式

1. 餓漢式(Eager Initialization)

特點:類加載時立即創建實例,線程安全但可能浪費資源。

public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;}
}

優點:實現簡單,線程安全。
缺點:實例在類加載時創建,即使未被使用。


在這里插入圖片描述

2. 懶漢式(Lazy Initialization)

特點:延遲實例化,但需處理線程安全問題。

public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static synchronized LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}

優點:按需創建實例。
缺點:同步方法導致性能下降。


3. 雙重檢查鎖(Double-Checked Locking)

特點:減少同步開銷,需使用volatile防止指令重排。

public class DCLSingleton {private static volatile DCLSingleton instance;private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance == null) {synchronized (DCLSingleton.class) {if (instance == null) {instance = new DCLSingleton();}}}return instance;}
}

優點:兼顧線程安全和性能。
缺點:實現較復雜,需注意JDK版本兼容性。


4. 靜態內部類(Static Inner Class)

特點:利用類加載機制保證線程安全。

public class InnerClassSingleton {private InnerClassSingleton() {}private static class Holder {static final InnerClassSingleton instance = new InnerClassSingleton();}public static InnerClassSingleton getInstance() {return Holder.instance;}
}

優點:延遲加載,線程安全,無需同步。
缺點:無法通過參數初始化實例。


5. 枚舉單例(Enum Singleton)

特點:由JVM保證唯一性,防止反射和序列化破壞。

public enum EnumSingleton {INSTANCE;public void doSomething() {// 方法實現}
}

優點:天然線程安全,防反射和序列化攻擊。
缺點:無法繼承其他類,不夠靈活。


在這里插入圖片描述

二、單例模式的使用場景

  1. 全局配置管理
    例如,系統配置類需要全局唯一實例,確保配置一致。

  2. 日志記錄器
    統一管理日志輸出,避免多個實例導致資源競爭。

  3. 數據庫連接池
    維護唯一的連接池實例,高效管理數據庫連接。

  4. 緩存系統
    緩存數據需要全局訪問,避免重復創建緩存實例。

  5. 硬件資源訪問
    如打印機服務,需統一調度硬件資源。


三、注意事項與潛在問題

  1. 線程安全
    懶漢式需通過同步或雙重檢查鎖確保線程安全。

  2. 反射攻擊
    普通單例可能被反射調用構造函數,需在構造器中添加防護:

    private Singleton() {if (instance != null) {throw new IllegalStateException("Instance already exists");}
    }
    
  3. 序列化與反序列化
    實現Serializable接口時,需重寫readResolve方法:

    protected Object readResolve() {return getInstance();
    }
    
  4. 測試困難
    單例的全局狀態可能導致測試耦合,可通過依賴注入(如Spring容器管理)解耦。

  5. 過度使用
    濫用單例會提高代碼耦合度,應僅在需要嚴格唯一實例時使用。


在這里插入圖片描述

四、總結

實現方式線程安全延遲加載防反射防序列化適用場景
餓漢式????簡單場景,實例輕量
懶漢式(同步)????需要延遲加載,性能不敏感
雙重檢查鎖????高性能要求的延遲加載
靜態內部類????推薦的延遲加載方式
枚舉????高安全性要求(推薦方式)

最佳實踐

  • 優先選擇枚舉單例靜態內部類實現。
  • 避免通過單例傳遞全局狀態,盡量依賴接口編程。
  • 在框架(如Spring)中,盡量使用容器管理的單例Bean而非手動實現。

通過合理選擇實現方式,單例模式能有效管理全局資源,但需謹慎使用以避免設計上的陷阱。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71270.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71270.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71270.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【前端基礎】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)

HTML結構 一個HTML包含以下部分&#xff1a; 文檔類型聲明html元素 head元素body元素 例&#xff08;CSDN&#xff09;&#xff1a; 一、文檔類型聲明 HTML最一方的文檔稱為&#xff1a;文檔類型聲明&#xff0c;用于聲明文檔類型。即&#xff1a;<!DOCTYPE html>…

文本挖掘+情感分析+主題建模+K-Meas聚類+詞頻統計+詞云(景區游客評論情感分析)

本文通過情感分析技術對景區游客評論進行深入挖掘,結合數據預處理、情感分類和文本挖掘,分析游客評價與情感傾向。利用樸素貝葉斯和SVM等模型進行情感預測,探討滿意度與情感的關系。通過KMeans聚類和LDA主題分析,提取游客關心的話題,提供優化建議,為未來研究提供方向。 …

【實戰 ES】實戰 Elasticsearch:快速上手與深度實踐-2.2.2線程池配置與寫入限流

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 Elasticsearch批量寫入性能調優&#xff1a;2.2.2 線程池配置與寫入限流深度實踐1. 線程池核心機制解析1.1 Elasticsearch線程池架構1.2 Bulk線程池工作模型 2. 寫入場景線程…

VSCode 與 Vim 插件 的 復制粘貼等快捷鍵沖突,優先使用 VSCode 的快捷鍵

VSCode 與 Vim 插件 的 復制粘貼等快捷鍵沖突&#xff0c;優先使用 VSCode 的快捷鍵 在 VSCode 中&#xff0c;如果你發現 Vim 插件&#xff08;如 VSCodeVim 擴展&#xff09;與 VSCode 的默認復制粘貼快捷鍵&#xff08;CtrlC / CtrlV&#xff09;沖突&#xff0c;并且你想優…

tsconfig.json 配置清單

tsconfig.json 配置清單 基礎結構 {"compilerOptions": {// 編譯選項},"include": [// 指定需要編譯的文件或目錄],"exclude": [// 指定不需要編譯的文件或目錄],"extends": "./base-tsconfig.json","files": […

springboot可以同時處理多少個請求

源碼 ServerProperties Tomcat 配置 參數解析 必須要先建立連接&#xff0c;再用線程處理。 比如max-connection最大連接數&#xff0c;accept-count相當于隊列容量。總連接數二者和 min-spare-treads 核心線程數默認10&#xff0c;max-threads最大線程數默認200。 正常…

Spring 三級緩存 vs 二級緩存:深度解析循環依賴的終極解決方案

目錄 一. 循環依賴的本質矛盾 1. 什么是循環依賴&#xff1f; 2. 矛盾的核心 二. 三級緩存架構解析 三級緩存工作流程圖?編輯 三、為什么必須三級緩存&#xff1f; 1. 二級緩存的致命缺陷 2. 三級緩存的精妙設計 四、場景推演&#xff1a;三級緩存如何解決代理問題 …

視頻流暢播放相關因素

視頻播放的流暢度是一個綜合性問題&#xff0c;涉及從視頻文件本身到硬件性能、網絡環境、軟件優化等多個環節。以下是影響流暢度的關鍵因素及優化建議&#xff1a; 一、視頻文件本身 1. 分辨率與幀率 1.問題&#xff1a;高分辨率&#xff08;如4K&#xff09;或高幀率&#…

金融項目實戰

測試流程 測試流程 功能測試流程 功能測試流程 需求評審制定測試計劃編寫測試用例和評審用例執行缺陷管理測試報告 接口測試流程 接口測試流程 需求評審制定測試計劃分析api文檔編寫測試用例搭建測試環境編寫腳本執行腳本缺陷管理測試報告 測試步驟 測試步驟 需求評審 需求評…

LeetCode 25 - K 個一組翻轉鏈表

LeetCode 25 - K 個一組翻轉鏈表 這道題是一個典型的鏈表操作題&#xff0c;考察我們對鏈表的精確操作&#xff0c;包括反轉鏈表、分組處理、遞歸和迭代的結合應用等。還可以通過變體問題延伸到優先隊列操作、歸并、分塊等&#xff0c;這使得它成為面試中的高頻考題之一。 題目…

Leetcode 54: 螺旋矩陣

Leetcode 54: 螺旋矩陣 是一道經典的矩陣遍歷模擬題目&#xff0c;要求我們以螺旋順序遍歷一個二維數組。這個問題在面試中非常經典&#xff0c;考察模擬、數組操作以及邏輯清晰度。掌握本題的高效解法可以迅速給面試官留下好印象。 適合面試的解法&#xff1a;邊界法&#xff…

abseil-cpp:環境搭建

參考: https://abseil.io/docs/cpp/quickstart-cmake abseil-cpp.git/dd4c89b abseil-cpp.git/20240722.1 1. clone代碼倉庫、編譯 git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/ #/app/abseil-cpp/.git/config git checkout 20240722.1git rev-pa…

Storm實時流式計算系統(全解)——下

storm編程案例-網站訪問來源實時統計-需求 storm編程-網站訪問來源實時統計-代碼實現 根據以上條件可以只寫一個類&#xff0c;我們只需要寫2個方法和一個main&#xff08;&#xff09;&#xff0c;一個讀取/發射&#xff08;spout&#xff09;。 一個拿到數據統計后發到redis…

什么是SYN洪范攻擊?

文章目錄 一、什么是SYN洪范攻擊&#xff1f;二、SYN泛洪攻擊原理2.1 TCP 三次握手過程2.2 SYN攻擊過程 三、防御措施 一、什么是SYN洪范攻擊&#xff1f; SYN洪泛攻擊&#xff08;SYN Flood&#xff09;發生在OSI第四層&#xff0c;是一種基于?TCP協議三次握手漏洞?的DoS&a…

【嵌入式】MQTT

MQTT 文章目錄 MQTT安裝簡介MQTT客戶端代碼 安裝 安裝Paho MQTT C庫: sudo apt-get install libpaho-mqtt3-dev頭文件包含&#xff1a; #include "MQTTClient.h"編譯選項&#xff1a; gcc -o $ $^ -lpaho-mqtt3c簡介 MQTT協議全稱是&#xff08;Message Queuing…

ubuntu離線安裝nvidia-container-runtime

參考文章 ubuntu系統docker20.4版本安裝nvidia-container-runtime3.11.0-1版本(離線安裝nvidia-docker) - jokerMM - 博客園 https://zhuanlan.zhihu.com/p/15194336245 一、軟件地址 Index of /nvidia-docker/libnvidia-container/stable/ 從上述地地址——進入對應系統—…

用Python+Flask打造可視化武俠人物關系圖生成器:從零到一的實戰全記錄

用PythonFlask打造可視化武俠人物關系圖生成器&#xff1a;從零到一的實戰全記錄 一、緣起&#xff1a;一個程序小白的奇妙探索之旅 作為一個接觸Python僅13天的編程萌新&#xff0c;我曾以為開發一個完整的應用是遙不可及的事情。但在DeepSeek的幫助下&#xff0c;我竟用短短…

RPA 職業前景:個人職場發展的 “新機遇”

1. RPA職業定義與范疇 1.1 RPA核心概念 機器人流程自動化&#xff08;RPA&#xff09;是一種通過軟件機器人模擬人類操作&#xff0c;自動執行重復性、規則性任務的技術。RPA的核心在于其能夠高效、準確地處理大量數據和流程&#xff0c;減少人工干預&#xff0c;從而提高工作…

Full GC 排查

在 Java 中&#xff0c;Full GC&#xff08;完全垃圾回收&#xff09;會對整個堆&#xff08;包括年輕代和老年代&#xff0c;甚至可能包括永久代/元空間&#xff09;進行垃圾回收&#xff0c;通常會導致較長的停頓&#xff08;STW&#xff0c;Stop-The-World&#xff09;。如果…

go語言中字符串嵌套

在Go語言中&#xff0c;字符串嵌套通常是指在字符串中包含另一個字符串。可以通過以下幾種方式實現&#xff1a; 1. 使用雙引號和轉義字符 如果需要在字符串中嵌套雙引號&#xff0c;可以使用轉義字符 \ 來表示內部的雙引號。例如&#xff1a; s : "He said, \"He…