安全執行緒且按需構建的單例模式,線程構建
單例模式,即保證某個類只有一個執行個體,網上有很多構造單例的方法,或多或少有其缺陷。如DCL(double check lock)模式,不能保證對象能被正確發布。
使用靜態變數
public class CarFactory { private static CarFactory instance = new CarFactory(); private CarFactory(){ } public static CarFactory getInstance(){ return instance; }}
這個能保證安全性,但是在不需要引用對象的instance時,對象也可能被建立,會造成資源浪費
Double Check Lock(DCL)
public class CarFactory { private static CarFactory instance = null; private CarFactory(){ } public static CarFactory getInstance(){ if(instance == null){ synchronized (CarFactory.class){ if(instance == null){ instance = new CarFactory(); } } } return instance; }}
這個是網上流傳的非常廣泛的單例模式構造方法,據說既能保證安全性,又能按需建立。但是仔細想想,線上程A和線程B同時調用getInstance()方法時,線程A調用了instance = new CarFactory(),但是對象還沒有初始化完畢,這時instance已經不為null,而線程B會認為instance不為null,直接使用instance。這就會造成引用逸出,根據JMM,線程A中初始的資料對線程B的可見度沒法保證。這可能會產生很嚴重的後果
安全執行緒&&按需建立
public class CarFactory { private CarFactory(){ } public static class SingleInstance{ static CarFactory instance = new CarFactory(); } public static CarFactory getInstance(){ return SingleInstance.instance; }}只有在調用getInstance()方法時,才能建立CarFactory執行個體,而且保證了執行緒安全性。