凯哥Java■Java并发编程之验证volatile指令重排-理论篇( 二 )


3:内存系统的重排序
通过之前的学习 , 我们知道了处理器和主内存之间还存在一二三级缓存 。 这些读写缓存的存在 , 使得程序的加载和存取操作 , 可能是乱序无章的 。
指令重排序的流程图
通过上面介绍 , 我们可以知道从程序员写的Java源码到处理器真正实际执行的指令序列 , 会经历如下图的过程:
凯哥Java■Java并发编程之验证volatile指令重排-理论篇
文章图片
执行顺序:
源码编译器优化重排序(第一次排序)指令重排序(第二次)内存重排序(第三次)最终指向的指令 。
无论是第一次编译器的重排序还是第二、三次的处理器重排序 。 这些重排序当在多线程的场景下可能会出现线程可见性的问题 。
如在多线程的情况下 , 单例模式就不安全了 。
为了解决这个问题 , JMM允许编译器在生成指令顺序的时候 , 可以插入特定类型的内存屏障来禁止指令重排序 。
当一个变量使用volatile修饰的时候 , volatile关键字就是内存屏障 。 当编译器在生成指令顺序的时候 , 发现了volatile,就直接忽略掉 。 不再重排序了 。
示意图:
凯哥Java■Java并发编程之验证volatile指令重排-理论篇
文章图片
证明volatile禁止指令重排演示代码 , 欢迎继续学习下一篇文章


推荐阅读