GOF(一)-單例模式(通過嵌套內部類的方式)【推薦】

單例模式(Singleton Pattern)

單例:即單個實例,實例需要new,所以是 創建型

單例模式特點:
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。

懶漢式和餓漢式主要是加載時間存在差別,即是否是在構造函數中new,這其實是類加載的相關知識,這裏不再贅述。


通過 內部嵌套類 的方式編寫單例模式

代碼如下:

public class Singleton {
    
    private Singleton() {
        System.out.println("Sigleton的無參構造函數初始化了");
    }

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

	// 內部嵌套類,注意是private,只能夠在Singleton中使用
    private static class InnerClass {

        private static Singleton instance = null;
        // static會被提前執行,具體知識可以從網上查找 加載順序相關的內容
        static {
            System.out.println("InnerClass 靜態代碼初始化了");
            instance = new Singleton();
        }
    }
}

測試代碼:

	public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        
		// 用==來比較是否爲同一個對象
        System.out.println(instance == instance1);

    }

加載順序(這裏只提及方法,不提及常量的加載):

  1. InnerClass的static{} 給自己的instance賦值
  2. Singleton的無參構造函數Singleton()
  3. Singleton.getInstance()調用SingletongetInstance()
  4. InnerClass中的instance已經賦過值了,直接return InnerClass.instance;返回
  5. 再次執行 Singleton instance1 = Singleton.getInstance();時直接 return InnerClass.instance;返回

測試結果:

InnerClass 靜態代碼初始化了
Sigleton的無參構造函數初始化了
true  // instance == instance1

補充內容:

雙檢鎖/雙重校驗鎖(DCL,即 double-checked locking)

這種方式採用雙鎖機制,安全且在多線程情況下能保持高性能。
代碼如下:

public class Singleton {

    private volatile static Singleton instance = null;

    private Singleton() {
        System.out.println("Sigleton的無參構造函數初始化了");
    }

    public static Singleton getInstance() {
    	// 如果沒有這個判斷,線程會排隊等synchronized的鎖
    	// 等拿到鎖,判斷髮現instance不爲null 就白等了
    	// 而且沒拿過鎖的線程還不知道,繼續傻等,白白浪費性能
        if (instance == null) { 
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}

具體測試與上面相同,當然可以開多線程進行測試這裏不再贅述。

最後的補充:

枚舉也是一種單例模式!!!

代碼已經上傳到Git:請點擊訪問

如果大家對於單例模式還有更多的使用技巧和使用心得,歡迎評論並在評論中分享自己的鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章