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 synchronized Singleton getInstance() {
if (instance == null) instance = new Singleton();
return instance;
}
}
特點:延遲加載、線程安全。
缺點:每次調用同步、效能極差。
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() { return Holder.INSTANCE; }
}
原理:JVM 類加載機制保證線程安全與延遲初始化。
優點:線程安全、延遲加載、無同步開銷、代碼簡潔。
推薦:⭐⭐⭐⭐⭐
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) instance = new Singleton();
}
}
return instance;
}
}
關鍵:`volatile` 禁止指令重排。
優點:延遲加載、高併發效能較好。
缺點:代碼較複雜、JDK 5+ 才可靠。
public enum Singleton {
INSTANCE;
public void doBusiness() {}
}
優點:防反射破壞、防序列化破壞、線程安全、語法最簡潔。
推薦:⭐⭐⭐⭐⭐ (Josh Bloch 推薦)
| 實現 | 線程安全 | 延遲加載 | 效能 | 防反射 | 防序列化 | 代碼複雜度 |
|---|---|---|---|---|---|---|
| 餓漢式 | ✓ | ✗ | 極高 | ✗ | 需 readResolve | 低 |
| 同步方法 | ✓ | ✓ | 低 | ✗ | 需 readResolve | 低 |
| 靜態內部類 | ✓ | ✓ | 極高 | ✗ | 需 readResolve | 低 |
| DCL | ✓ (JDK5+) | ✓ | 高 | ✗ | 需 readResolve | 中 |
| 枚舉 | ✓ | ✓ | 極高 | ✓ | ✓ | 極低 |
// 反射攻擊防禦 (非枚舉)
private Singleton() {
if (instance != null) throw new IllegalStateException("單例已存在");
}
// 序列化破壞防禦
private Object readResolve() { return INSTANCE; }
// 克隆破壞防禦
@Override protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("單例不可克隆");
}
// Spring
@Component @Scope("singleton")
public class ConfigManager { ... }
// 使用處注入
@Autowired ConfigManager configManager;
容器管理生命週期、依賴關係、AOP 代理、測試替換,優於手寫單例。
「單例模式理解容易,正確實現難。現代 Java 開發中,優先交給 DI 容器管理;必須手寫時,枚舉與靜態內部類是最佳平衡點。」