浅谈指令重排序

128 阅读1分钟

指令重排

为什么会出现指令重排序?

as-if-serial看上去像序列化:CPU为了提高效率乱序执行,只要不影响单线程最终一致性。

dcl单列 double-check-lock

第一个线程在new对象时候,可能指令重排序让new对象的过程被打断,使得对象成为一个半初始化对象。

之后的线程对对象进行判空之后,可能返回一个半初始化的对象。因为此时对象不为空而是一个半初始化对象。

此时需要阻止指令重排

cpu层

底层级别使用内存屏障:前面的必须执行完,后面的才能执行 jvm层

用volatile修饰的变量,对它进行写入时候在前后加入store-store-barrier和store-load-barrier;在读取它时候在前后加入,load-store-barrier和 load-load-barrier。

JSR是Java Specification Requests的缩写,意思是“Java 规范提案”

JSR对内存屏障的规范

  • LoadLoad屏障:对于这样的语句Load1;LoadLoad;Load2

    在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

  • StoreStore屏障:对于这样的语句Store1;StoreStore;Store2

    在Store2及后续写入操作执行前,保证Store1的写入操作对其他处理器可见。

  • LoadStore屏障:对于这样的语句Load1;LoadStore;Store2

    在Store2及后续写入操作被刷新到内存之前,保证Load1要读取的数据被读取完毕。

  • StoreLoad屏障:对于这样的语句Store1;StoreLoad;Load2

    在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。


如果有什么不对的地方欢迎指正 :)