Java 單例模式(Singleton Pattern)詳解
🌟 什么是單例模式?
單例模式確保一個類只有一個實例,并提供一個全局訪問點來訪問它。
🧠 使用場景
- 配置管理類(如讀取配置文件)
- 日志工具類(如 Log4j 的 Logger)
- 數據庫連接池
- 緩存管理
- 線程池
? 實現方式(Java)
方式一:餓漢式(類加載時就實例化)
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}
- 優點:簡單、線程安全
- 缺點:類加載時就創建實例,可能浪費資源
方式二:懶漢式(線程不安全)
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
- 缺點:多線程環境會創建多個實例
方式三:懶漢式 + synchronized(線程安全)
public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
- 缺點:加鎖影響性能
方式四:雙重檢查鎖(DCL)
public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
- 優點:懶加載 + 線程安全 + 性能較好
volatile
防止指令重排
方式五:靜態內部類
public class Singleton {private Singleton() {}private static class Holder {private static final Singleton instance = new Singleton();}public static Singleton getInstance() {return Holder.instance;}
}
- 優點:利用 JVM 機制,線程安全 + 懶加載 + 高性能
方式六:枚舉實現(最推薦)
public enum Singleton {INSTANCE;public void doSomething() {System.out.println("Doing something...");}
}
- 優點:防反射、防反序列化、天然線程安全
- 缺點:不能延遲加載
🔐 防止反射與反序列化破壞單例
防反射
private Singleton() {if (instance != null) {throw new RuntimeException("反射破壞單例!");}
}
防反序列化
private Object readResolve() {return instance;
}
📌 各方式對比
實現方式 | 是否懶加載 | 是否線程安全 | 推薦度 |
---|---|---|---|
餓漢式 | 否 | 是 | ★★ |
懶漢式 | 是 | 否 | ★ |
synchronized | 是 | 是 | ★★ |
DCL | 是 | 是 | ★★★★ |
靜態內部類 | 是 | 是 | ★★★★★ |
枚舉 | 否 | 是 | ★★★★★(最安全) |