如何正確實現一個單例設計模式
阿新 • • 發佈:2018-12-21
設計模式中的單例,是最常用,也算是比較簡單的一個了。我們都知道,要想保證只有一個例項,通常採用加鎖和雙重檢查的方式來實現單例,程式碼如下。
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; } }