未使用volatile下的双重检查锁
public class DoubleCheckedLocking { // 1 |
双重检查锁锁定了instance = new Instance();
创建了一个对象,这一行代码可以分解为下面三行伪代码:
memory = allocate(); // 1. 分配对象的内存空间 |
上述的伪代码中,2和3之间,可能会被重排序,在一些JIT编译器上,这种重排序是真实发生的。
2和3之间重排序之后的执行时序如下:
memory = allocate(); // 1. 分配对象的内存空间 |
重排序之后,就有可能拿到没有经历初始化的对象,这是非常危险的。