單例模式確保一個類在整個應用程序生命週期中,僅存在一個實例,並提供全局訪問點。這在需要共享資源的場景極為常見,例如:多線程讀取同一配置文件時,將配置封裝為單例對象,不僅便於數據操作,更能保證所有線程讀取的是同一份內存中的配置實例,避免數據不一致。

要確保對象唯一性,需遵循以下設計思想:
new 關鍵字直接實例化getInstance() 方法,由類自己控制實例的創建與分發public class Car {
private Car() { }
public static Car getInstance() {
return new Car(); // 每次調用都創建新對象,違背單例初衷
}
}
public class Car {
private static Car car = new Car(); // 類加載時即創建實例
private Car() { }
public static Car getInstance() {
return car; // 始終返回同一個實例
}
}
類加載階段即完成實例化,天然線程安全,無需額外同步機制。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
優點:實現簡單,類加載機制保證線程安全。
缺點:若實例從未被使用,會造成內存浪費;無法實現延遲加載。
僅在首次調用 getInstance() 時創建實例,實現按需加載。
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

在多線程環境下,線程 A 判斷 instance == null 為真,尚未執行 new Singleton() 時,線程 B 同樣通過判斷,導致創建兩個實例,破壞單例約束。

在 getInstance() 方法上加 synchronized 關鍵字,鎖住類的字節碼對象,確保同一時間僅有一個線程能執行實例化邏輯。
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
注意:同步會降低性能,僅首次調用需要同步,後續調用無需鎖。生產環境推薦使用雙重檢查鎖(DCL)或靜態內部類實現高性能線程安全單例。