问题根源:
1. 可见性问题:多核 CPU 缓存导致
由于硬件之间访问速度的差异,CPU 会从内存中读取数据并缓存在寄存器中。这样当某 CPU 对内存中的数据修改时就导致了内存与其它 CPU 中的数据不一致。
2. 原子性问题:线程切换导致
高级语言的原子操作并不等同于CPU指令的原子操作。赋值时有线程切换会导致问题。如下图。
3. 有序性问题:编译优化造成
java 编译器在编译期间会对源码优化,从而导致的问题。如下代码会先分配内存再初始化对象。
public class Singleton {
static Singleton instance;
/**
* 获取Singleton对象
*/
public static Singleton getInstance(){
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}