在Java中實現單例模式有幾種方式,但最常見的是懶漢式和餓漢式。我們先來看一個簡單的懶漢式實現:
public class Singleton {private static Singleton instance;private Singleton() {} // 構造方法私有化,防止外部實例化public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
這種方式的特點是在第一次調用getInstance()
方法時才會創建實例,實現了懶加載。但是,這種方式在多線程環境中可能會創建多個實例,因此不是線程安全的。
為了解決這個問題,我們可以使用雙重檢查鎖定(DCL):
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
關鍵字確保多線程環境下的可見性,同時通過兩次檢查instance
的值來保證只創建一個實例。
除了懶漢式,還有餓漢式實現,它在類加載時就完成了實例化,因此天生是線程安全的:
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {} // 構造方法私有化,防止外部實例化public static Singleton getInstance() {return instance;}
}
餓漢式的優點是簡單且線程安全,但如果該實例占用資源較多,而應用中實際并未使用到,就會造成資源的浪費。