volatile禁止指令重排
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
当一个线程进入开始在内存new对象空间的时候,因为CPU底层会进行指令重排,如果此时字节码发生先new 再 astore在invokespecial的时候,此时在invokespecial调用之前线程对象半初始化,产生与堆空间对象的链接,此时其他的线程进入判断instance 不为空然后进行其他操作此时就会出现问题,而volatile可以禁止指令重排,这样就可以避免出现问题
操作系统的底层屏障lfence mfence sfence
volatile如何解决指令重排
1volatile 源码层级
2ACC_VOLATILE 字节码层级
3JVM的内存屏障 JVM层级
屏障两边的指令不能重排**
4hotspot实现 hotspot层级
5正真意义上的电信号层级