volatile关键字的作用

要了解这个关键字的作用,我们需要知道两个概念

  1. 可见性
    Java编程语言中允许线程访问共享变量。为了确保共享变量能够被准确和一致的更新,线程应该确保通过排它锁单独获得这个变量。
  2. 指令重排
    在编程执行过程中为了性能考虑,编译器和CPU可能会对指令重新排序。对于并发多线程场景下,指令重排会产生不确定的执行效果。

所以volatile针对可见性

  • volatile关键字修饰的共享变量可以提供这种可见性范围,也叫 读写可见
  • 被volatile修饰的共享变量在转换成汇编语言时,会加上一个以lock为前缀的指令,当CPU发现这个指令时,立即将当前内核高速缓存行的数据回写到内存,同时使在其他内核里缓存了该内存地址的数据无效
  • 在早期的CPU中,是通过在总线加LOCK锁的方式实现的,但这种方式开销较大。所以Intel开发了缓存一致性协议,也就是MESI协议,来解决缓存一致性
  • 好处 volatile是一种非锁机制,这种机制可以避免锁机制引起的线程上下文切换和调度问题。所以,volatile的执行成本比synchronized更低
  • 不足 volatile关键字只能保证可见性,不能保证原子性的操作

针对指令重排

public volatile boolean sign;
descriptor: Z
flags: ACC_PUBLIC, ACC_VOLATILE

从字节码层面,添加ACC_VOLATILE,在汇编指令的打印会有lock addl$0x0,(%rsp)s
从JVM层面,JMM提供了8个Happen-Before规则来约束数据之间竞争,4个内存屏障(LL LS SL SS)和As-if-serial
从硬件层面,sfence、Ifence、mfence

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容