指令重排序,包括编译器重排序和处理器重排序(指令级并行技术或缓存)(
JVM(十一)Java指令重排序_keep_trying_gogo的博客-CSDN博客_jvm指令重排序
)。
单例模式中的双重校验方式(单例模式 | 菜鸟教程)加了volatile关键字双重检查锁单例模式为什么要用volatile关键字? - 百度文库。
线程1可能分配了内存、变量赋值、实例化,线程2在线程1变量赋值后,返回变量,此时的变量是没有执行实例化的方法的变量。单线程下使用变量前JVM本身有等实例化结束的机制,但多线程没有。
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
指令无序包括指令重排序和线程工作内存(线程本地内存)和主内存同步延迟。只有volatile能避免指令重排序。同步锁可以避免线程工作内存和主内存同步延迟。
volatile依靠内存屏障避免指令重排序。
内存屏障分三种:写屏障(store barrier)、读屏障(load barrier)和全屏障(Full Barrier)。
内存屏障指令分四种:LoadLoad Barriers、StoreStore Barriers、LoadStore Barries、StoreLoad Barries。
volatile和final不能修饰同一个变量(volatile 和final 为什么不能同时修饰一个字段? - SegmentFault 思否)。