單例模式詳解
只能生成一個實例的類是實現了Singleton(單例)模式的類型。實現單例模式的程式碼比較短,在面試中經常被提及,這篇隨筆介紹幾種常見的實現方式。
public class Singleton { // 構造方法私有化 private Singleton(){} // 類載入就創建實例 private static Singleton instance = new Singleton(); // 對外提供獲取實例的方法 public static Singleton getInstance() { return instance; } }
2.懶漢模式
最基本的實現方式,執行緒不安全。
public class Singleton { // 構造方法私有化 private Singleton(){} // 靜態實例 private static Singleton instance; // 對外提供獲取實例的方法,需要的時候再創建實例 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
3.懶漢模式,執行緒安全
public class Singleton { // 構造方法私有化 private Singleton(){} // 靜態實例 private static Singleton instance; // 對外提供獲取實例的方法,需要的時候再創建實例 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
4.雙重校驗鎖(double-checked locking, DCL)
在實例創建之前我們需要對方法加鎖,那麼創建以後就無需重複加鎖操作,盡最大可能提高程式的執行效率。對上面的程式碼進行改進,這種方式適用於有特殊需求的場景:
public class Singleton { // 構造方法私有化 private Singleton(){} // 靜態實例 private static Singleton instance; public static Singleton getInstance() { if (instance == null) { // 對Singleton類加鎖 synchronized(Singleton.calss) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
5.靜態內部類
這種方法會在Singleton類內部再創建一個靜態內部類,只有顯示調用 getInstance()時,實例才會被創建。這種方式適用於靜態域需要延遲初始化的場景。
public class Singleton { private Singleton (){} private static class SingletonHolder { // final修飾,無法再指向其他對象 private static final Singleton INSTANCE = new Singleton(); } // 鎖定方法,防止子類繼承重寫方法 public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }
參考資料:《Head First 設計模式》
《劍指offer》第二版