前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅析JAVA内存模型之volatile

浅析JAVA内存模型之volatile

作者头像
一个架构师
发布2022-06-20 20:01:46
1520
发布2022-06-20 20:01:46
举报
文章被收录于专栏:从码农的全世界路过

我们抛开复杂的Java内存模型(JMM)规范, 用最简单的方法看下一个普通变量为什么是线程不安全的; volatile又是怎么做到数据的轻量级同步的.

首先, 线程在运行时, 并不是直接从主内存中去读写变量的, 因为这种读写速度是跟不上CPU计算速度的.

CPU不会直接读/写主内存中变量数据, 而是将寄存器中的数据先写入L1/L2 cache, 在写入主内存中, 读的过程也是先读入L1/L2 cache中, 寄存器从L1/L2 cache中读取计算.

类似的, java线程内存模型也有自己的工作内存, CPU先将数据读取到工作内存中, 在进行计算;

需要注意的是, 这时工作内存中的数据, 都是原数据的变量副本; 所以多线程的情况下, 各线程间是无法访问和感知变量修改的, 这样也就造成了线程不安全问题.

那volatile是如何做到线程安全的呢?

在说明volatile之前, 我们先完善一个知识点, 这些工作内存中的变量并不是直接与主内存交互的, 而是通过总线进行读写操作的.

使用volatile修饰的变量在编译器编译后, 会多出一个lock前缀的汇编指令, 相当于一个内存屏障, 会将修改的数据强制写入主内存, 而不是缓存在工作内存中.

在变量更新时, 根据总线MESI缓存一致性协议, 其他CPU通过总线嗅探机制, 感知变量发生变化, 并将自己工作内存中的变量副本无效化.

可见volatile变量是保证了线程间的可见性; 但并不保证原子性, 在多线程同时读写的时候是需要借助CAS或者锁相关机制的.

根据java内存模型中的happens-before原则, volatile变量还会保证有序性, 也就是对一个变量的写操作先行发生于后面对这个变量的读操作;

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从码农的全世界路过 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档