
原文地址:LoveDev
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一利花,該模式確保一個類只有一個實例

單例模式
懶漢式,線程不安全
class LazySingleton {
private static LazySingleton instance;
private LazySingleton (){}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
懶漢式使用懶加載模式灾而,但是在多線程環(huán)境中調(diào)用 getInstance()
就會創(chuàng)建多個實例
懶漢式,線程安全
class SynchronizedLazySingleton {
private static SynchronizedLazySingleton instance;
private SynchronizedLazySingleton(){}
//添加synchronized關(guān)鍵字
public static synchronized SynchronizedLazySingleton getInstance() {
if (instance == null) {
instance = new SynchronizedLazySingleton();
}
return instance;
}
}
給 getInstance()
方法加上 synchronized
關(guān)鍵字實現(xiàn)線程安全商乎,但是該方法效率上有問題攀细,任何時候只能有一個線程調(diào)用 getInstance()
獲取實例箫措,而且實例第一次創(chuàng)建之后就不需要同步操作
餓漢式,線程安全
class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return instance;
}
}
實例被 static
final
修飾哎迄,類加載時就會初始化回右,但它不是懶加載模式,如果 HungrySingleton
實例的創(chuàng)建需要某個條件參數(shù)漱挚,這種寫法就不能實現(xiàn)
雙重檢驗鎖
class DoubleCheckedSingleton {
private volatile static DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {}
public static DoubleCheckedSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
為了避免在多線程環(huán)境中執(zhí)行 instance = new DoubleCheckedSingleton()
造成指令重排序翔烁,添加 volatile 關(guān)鍵字修飾,禁止指令重排序優(yōu)化旨涝,拋開代碼可讀性來說這種寫法已經(jīng)完美了租漂,但是這樣你就滿足了嗎?沒有的話就接著看下去吧
靜態(tài)內(nèi)部類
class StaticSingleton {
private static class SingletonHolder {
private static final StaticSingleton INSTANCE = new StaticSingleton();
}
private StaticSingleton (){}
public static final StaticSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
該方法為 《Effective Java》上推薦的颊糜,它是懶漢式哩治,并且性能沒有缺陷
枚舉
enum EnumSingleton {
INSTANCE
}
最簡單的單例類,沒有之一衬鱼,還能防止序列化導致重新創(chuàng)建新的對象
思考
以上介紹的單例模式的寫法均在單一進程中有效业筏,如果是多進程環(huán)境中,這些寫法均不能保證實例的唯一性鸟赫,如何在多進程環(huán)境中保證單例模式的特性呢蒜胖?