1. 程式人生 > >如何正確實現一個單例設計模式

如何正確實現一個單例設計模式

設計模式中的單例,是最常用,也算是比較簡單的一個了。我們都知道,要想保證只有一個例項,通常採用加鎖和雙重檢查的方式來實現單例,程式碼如下。

public class SingletonTest {
    private SingletonTest(){

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

}

這種寫法的要點主要有如下幾個,1,私有建構函式,即不允許直接呼叫建構函式new一個物件。2,靜態例項。3,靜態獲取示例的方法。首先判斷instance是否為null,然後加鎖,然後再判斷instance是否為null,之後進行初始化。最後返回示例。

做到這些就足夠了嗎?並不是。

我們都知道,jvm的記憶體模型,jvm中的執行緒有自己的工作記憶體,jvm有主記憶體,工作記憶體是主記憶體的拷貝,工作記憶體和主記憶體直接並不是實時一致的。一個執行緒建立了單例物件後,別的執行緒並不一定可以立刻感知到。所以,以上程式碼中,instance還需要用volatile來修飾,才能真正做到單例模式。修改後的程式碼如下。

public class SingletonTest {
    private SingletonTest(){

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

}