面試中,面試官問起單例模式時,我們是否只乖乖地回答了七種單例模式呢
在單例模式的懶漢模式(線程安全實現(xiàn))中,為什么需要更進一步地改為DCL(Double check)?這里其實涉及到Singleten對象在創(chuàng)建時的指令重排序問題。
Singleton = new Singleton();
抽象為jvm指令為
memory = allocate(); //1:分配對象的內存空間
initInstance(memory); //2:初始化對象
instance = memory; //3:設置instance指向剛分配的內存地址
因為2、3指令并不互相依賴,jvm可能把指令優(yōu)化為
memory = allocate(); //1:分配對象的內存空間
instance = memory; //3:設置instance指向剛分配的內存地址
initInstance(memory); //2:初始化對象
而volicate又是怎么防止指令重排序的呢?
答:volatile關鍵字通過“內存屏障”來防止指令被重排序。
下面是基于保守策略的JMM內存屏障插入策略:
在每個volatile寫操作的前面插入一個StoreStore屏障。
在每個volatile寫操作的后面插入一個StoreLoad屏障。
在每個volatile讀操作的后面插入一個LoadLoad屏障。
在每個volatile讀操作的后面插入一個LoadStore屏障。
關于內存屏障可以參考下文
內存屏障