一、前言
volitale 知识点主要涉及JAVA内存模型的知识点,volitale提供了内存可见性和禁止指令重排的功能。
参考文章:https://blog.csdn.net/eff666/article/details/67640648
二、知识点
1.内存可见性
对变量进行访问和赋值时,观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
(1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
(2)它会强制将对缓存的修改操作立即写入主内存;
(3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内部缓存后再进行操作,但操作完后不知什么时候会写到内存。
如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写会到系统内存。这一步确保了如果有其他线程对声明了volatile变量进行修改,则立即更新主内存中数据。
但这时候其他处理器的缓存还是旧的,所以在多处理器环境下,为了保证各个处理器缓存一致,每个处理会通过嗅探在总线上传播的数据来检查 自己的缓存是否过期,当处理器发现自己缓存行对应的内存地址被修改了,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作时,会强制重新从系统内存把数据读到处理器缓存里。 这一步确保了其他线程获得的声明了volatile变量都是从主内存中获取最新的。
2.禁止指令重排
- 禁止指令重排的概念是:使用volitale变量所在代码作为一个界限,其前面的代码不能重新调整到后面,后面的也不能调整到前面。但是不能保证其前面的代码不会出现重新排序的情况,后面也是一样。
- volitale 通过内存屏障实现 禁止指令重排
来源:CSDN
作者:bxw1992
链接:https://blog.csdn.net/bxw1992/article/details/104390850