[漁夫也能懂設計模式] 單例模式(Singleton Pattern)

  什麼是單例模式?

單例模式:確保一個類只有一個實例,並提供一個全局訪問點

  單例模式有哪幾種?

第一種:懶漢式 線程不安全

public class Single_one {
    int val = 5;
    private static Single_one instance;
    private Single_one (){}

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

 很多人一提到單例模式想到的就是上面這種,很多書上也是這麼教我們的。這段代碼用了懶加載模式,但是有個致命的缺點-------線程不安全!

第二種:懶漢式 線程安全

public class Signle_lazy {
    private  static Signle_lazy instance;
    private Signle_lazy(){}
    int val = 5;
    public static synchronized Signle_lazy getInstance(){
        if(instance == null){
            instance = new Signle_lazy();
        }
        return  instance;
    }
}

 將getInstance方法設爲synchronized(同步)以後,雖然是解決了線程安全的問題,但是它並不高效。這就引出了雙重檢驗鎖模式(double checked locking pattern)。本文就不詳細講開說了,想要了解的小夥伴可以自行谷歌。
 下面是第三種適合初學者的單例模式:

第二種:餓漢式

public class Signle_hunger {
    int val = 20;
    //類加載時就初始化
    private static final Signle_hunger instance = new Signle_hunger();

    private Signle_hunger(){}

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

 它不是一種懶加載模式,單例會在加載類後一開始就被初始化。

第四種:靜態內部類 static nested class

public class Singleton {
    private static class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

 這種寫法仍然使用JVM本身機制保證了線程安全問題;由於 SingletonHolder 是私有的,除了 getInstance() 之外沒有辦法訪問它,因此它是懶漢式的;同時讀取實例的時候不會進行同步,沒有性能缺陷;也不依賴 JDK 版本。

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