首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

GoF 設計模式精講(一):單例模式的五種實現與最佳選型指南

     編輯:Java 綜合教學

單例模式核心使命

確保一個類在全局範圍內僅有一個實例,並提供一個全局訪問點獲取該實例。

典型應用場景

  • Windows 任務管理器
  • 專案配置文件讀取
  • 資料庫連接池(連接屬稀缺資源)
  • 作業系統文件管理系統
  • Application 上下文(Servlet/Android)
  • Spring 容器中 Bean 默認單例
  • Servlet 實例、Spring MVC/Struts1 控制器

優勢分析

  • 降低系統開銷:對象創建成本高(如讀取配置、初始化依賴)時,啟動時創建單例長駐記憶體。
  • 優化共享資源訪問:提供全局訪問點,如設計單例類管理所有數據表映射。

五種經典實現方式詳解

1. 餓漢式

特點:類加載時立即實例化,線程安全,調用效率高,但無法延遲加載。

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

靜態變量在類加載時初始化,JVM 保證只加載一次,天然線程安全。缺點:若類被加載但未使用,造成資源浪費。

2. 懶漢式

特點:首次調用時創建,延遲加載,但同步鎖導致併發效率低。

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

3. 雙重檢查鎖

特點:嘗試兼顧延遲加載與高併發,但因 JVM 指令重排序可能導致問題,不推薦使用(除非加 volatile)。

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

4. 靜態內部類式

特點:推薦使用。線程安全、調用效率高、實現延遲加載,完美結合餓漢與懶漢優點。

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

外部類無靜態屬性,不會在加載時實例化;調用 getInstance 時才加載內部類,類加載過程線程安全;static final 保證唯一實例。

5. 枚舉單例

特點:實現最簡潔,JVM 根本層面保證單例,天然防反射與序列化破壞,但無延遲加載。

public enum Singleton05 {
    INSTANCE;
    public void operation() { /* 業務邏輯 */ }
}

選型決策指南

  • 資源佔用小、無需延遲加載:枚舉 > 餓漢式
  • 資源佔用大、需延遲加載:靜態內部類 > 懶漢式

安全漏洞與防範

  • 反射破壞(除枚舉外):構造器中手動拋出異常防禦。
  • 序列化破壞(除枚舉外):實現 readResolve() 返回原實例。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved