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

Java 單例模式深度解析:七種寫法、線程安全、序列化破壞與最佳實踐

     編輯:Java 相關知識

單例模式確保類全局唯一實例,並提供全局訪問點。看似簡單,實則暗藏線程安全、反射破壞、序列化重建、類加載器隔離等深坑。

七種經典寫法對比

模式線程安全懶加載性能推薦度
餓漢式 (static final)✅❌極高⭐⭐⭐ (常用)
懶漢式 + synchronized✅✅低 (鎖粗)⭐
雙重檢查鎖 (DCL) + volatile✅✅高⭐⭐
靜態內部類✅✅高⭐⭐⭐⭐⭐ (最推薦)
枚舉單例✅❌高⭐⭐⭐⭐⭐ (防反射/序列化)

推薦寫法:靜態內部類


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

利用類加載機制保證線程安全與懶加載,無鎖、代碼簡潔、JVM 原生支持。

推薦寫法:枚舉 (Effective Java 作者 Josh Bloch 推薦)


public enum Singleton {
    INSTANCE;
    public void doSomething() { ... }
}

天然防反射攻擊 (構造器私有化最終由 JVM 強制)、天然防序列化重建 (JVM 保證枚舉常量唯一)、代碼最少。

常見破壞與防御

破壞手段原理防御
反射 setAccessible(true)暴力調用私有構造器構造器中檢查 if (INSTANCE != null) throw Exception;或用枚舉
反序列化readResolve() 返回新對象實現 readResolve() 返回 INSTANCE;或用枚舉
多類加載器不同 ClassLoader 加載同類視為不同類指定類加載器;OSGi/模塊化環境需謹慎設計

適用場景

  • 工具類 (工具類、常量管理)
  • 資源管理器 (線程池、連接池、緩存)
  • 配置中心 (讀取配置文件)
  • 狀態共享對象 (計數器、ID 生成器)

現代框架視角

Spring @Scope("singleton")、@Component 默認單例,由容器管理生命周期、依賴注入、AOP 代理,**遠優於手寫單例**。業務代碼優先使用框架單例,工具庫無框架依賴時才考慮枚舉/內部類。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved