public class Single {
private static volatile Single single;
public static Single getSingle(){
if (single==null){
synchronized (Single.class){
if (single==null){
single=new Single();
}
}
}
return null;
}
}
因为如果不用volatile修饰的话,在 single=new Single();会发生指令重排序,
Single的代码可以分解为三个部分
- 分配对象的内存空间
- 初始化对象
- 设置single指向内存空间
在JIT里,可能会将2与3进行重排序,在单线程里这里并不会发生什么问题,但是在多线程情况下,会出现下面的问题
时间 |
线程A |
线程B |
t1 |
A1:分配对象的内存空间 |
|
t2 |
A3:设置single指向内存空间 |
|
t3 |
B1:判断single是否为空 |
|
t4 |