在执行程序时,为了提高性能,处理器和编译器常常会对指令进行重排序;当然不能随意重排序,指令重排需要满足以下两个条件:
1.在单线程环境下不能改变程序运行的结果;
2.存在数据依赖关系的不允许重排序;
其实这两点可以归结于一点:happens-before规定的顺序不能改变,其他的JMM允许任意的排序;
从硬件架构上来说,指令重排序是指CPU采用了允许将多条指令不按照程序规定的顺序,分开发送给各个相应电路单元处理,而不是指令任意重排。
重排序分成三种类型:
1.编译器优化的重排序。编译器在不改变单线程程序语义放入前提下,可以重新安排语句的执行顺序;
2.指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序;
3.内存系统的重排序。由于处理器使用缓存和读写缓冲区,这使得加载和存储操作看上去可能是在乱序执行;
禁止指令的重排序
从Java源代码到最终实际执行的指令序列,会经过三种重排序;
但是,为了保证内存的可见性,Java编译器会在指令序列的适当位置插入内存屏障指令,来禁止特定类型的处理器重排序;
对于编译器的重排序