public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
instance 加 volatile 是否必要?若不加,instance = new Singleton() 後,其他執行緒是否可能暫時看不到?
synchronized 已保證可見性與有序性。synchronized,檢查 instance == null,建立物件,賦值給 instance。synchronized (unlock) → **發生 happens-before 邊緣**。synchronized (lock) → **保證看到 A 所有寫入**,包括 instance 參考與物件內部初始化完成狀態。volatile boolean flag 控制執行緒停止。volatile long/double 保證 64 位元讀寫原子。volatile ImmutableObj ref 確保其他執行緒看到完全初始化的物件。public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
Holder 類別初始化時的 INSTANCE 建構過程對所有執行緒可見。DCL + synchronized **不需要 volatile**;現代 Java 開發**首選靜態內部類**實現單例,簡潔、安全、高效。