指令重排
为什么会出现指令重排序?
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的写入对所有处理器可见。
如果有什么不对的地方欢迎指正 :)