單例模式的幾種實現方式

單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利于我們協調系統整體的行為。

通常單例模式在Java語言中,有兩種構建方式:

  • 懶漢式。指全局的單例實例在第一次被使用時構建。
  • 餓漢式。指全局的單例實例在類裝載時構建。

以下方式均線程安全

懶漢式(static)

不高效,因為在任何時候只能有一個線程調用 getInstance() 方法。但是同步操作只需要在instance == null調用時才被需要,即第一次創建單例實例對象時。雙重檢驗鎖改進。

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

懶漢式(static) | 雙重檢驗鎖(double checked locking pattern)

兩次檢查 instance == null,一次是在同步塊外,一次是在同步塊內。因為可能會有多個線程一起進入同步塊外的 if,如果在同步塊內不進行二次檢驗的話就會生成多個實例。此代碼也不完美,new Singleton()并非是一個原子操作。

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null)
            synchronized (Singleton.class) {
                if (instance == null)
                    instance = new Singleton();
            }
        return instance;
    }
}

懶漢式(static) | 靜態內部類(static nested class)

推薦。

public class Singleton {
    
    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

餓漢式(static final)

是一種懶加載模式(lazy initialization)。單例會在加載類后一開始就被初始化,即使客戶端沒有調用 getInstance()方法。

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

枚舉式(Enum)

最簡單。

public enum Singleton {
    INSTANCE;
}

總結

這篇博文只是自己梳理了一遍,有時間再完善完善。

參考資料

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容