DCL(Double Check Lock雙端檢鎖機制)單例模式:適用于多線程高并發(fā)場景
/**
* DCL(Double Check Lock雙端檢鎖機制)單例模式:適用于多線程高并發(fā)場景
*/
public class SingletonPattern {
//DCL機制不一定線程安全搓谆,原因是有指令重排序的存在眶俩,加入volatile可以禁止指令重排凌那,
//原因在于某一個線程執(zhí)行到第一次檢測,讀取到singletonPattern不為null時婴氮,singletonPattern的引用對象可能沒有完成初始化。
//創(chuàng)建對象分三步,1蒸痹、分配對象內存空間 2僻爽、初始化對象 3虫碉、設置singletonPattern指向剛分配的內存地址,此時singletonPattern != null
//步驟2和步驟3不存在數據依賴關系胸梆,而且五輪重排前還是重排后程序的執(zhí)行結果在單線程中并沒有改變敦捧,因此這種重排優(yōu)化是允許的。
private volatile static SingletonPattern singletonPattern = null;
private SingletonPattern(){
//對象創(chuàng)建成功后打印碰镜,如單例模式兢卵,應只打印一次
System.out.println(Thread.currentThread().getName() + " : " + "SingletonPattern!");
}
private static SingletonPattern getSingletonPattern (){
if(singletonPattern == null){
//如多個線程同時進入,那么在進行一次加鎖驗證绪颖,保證只創(chuàng)建一個對象
synchronized (SingletonPattern.class){
if(singletonPattern == null){
singletonPattern = new SingletonPattern();
}
}
}
//如果未加volatile導致指令重排秽荤,其他線程可能會直接返回未初始化的對象。
return singletonPattern;
}
public static void main(String[] args) {
for(int i = 0; i < 100 ; i++){
new Thread(() -> {
getSingletonPattern();
},String.valueOf(i)).start();
}
}
}