双重检测锁的单例模式之volatile
程序员文章站
2024-02-29 19:19:22
...
DCL(双重检测锁) 机制不一定线程安全,原因是有指令重排的存在,加入volatile可以禁止指令重排。
原因在于创建一个对象并不是原子操作,单线程的指令重排没有问题,但是多线程时,某一个线程在执行到第一次检测,读取到的instance不为null时,instance的引用对象可能没有完成初始化。
public class SingletonTest {
// 禁止指令重排
private static volatile SingletonTest instance = null;
private SingletonTest() {
System.out.println(Thread.currentThread().getName() + "\t 构造方法");
}
/**
* 双重检测机制
*
* @return
*/
public static SingletonTest getInstance() {
if (instance == null) {
synchronized (SingletonTest.class) {
if (instance == null) {
//此处分三步: | 可能重排指令:
//(1)分配内存 | (1)分配内存
//(2)创建对象在内存 | (2)instance指向该内存位置
//(3)instance指向该内存位置 | (3)创建对象在内存
instance = new SingletonTest();
}
}
}
return instance;
}
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
new Thread(() -> {
SingletonTest.getInstance();
}, String.valueOf(i)).start();
}
}
}
上一篇: 关于jdk1.8时间操作