Java 并发编程之volatile可见性,原子操作线程不安全

本文详细解释了volatile关键字的作用,如何确保线程可见性,以及为何在多线程环境下,不保证原子操作的线程安全性,通过MESI协议举例说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

volatile 关键字

在修饰的变量,在系统汇编的代码里会生成lock前缀,表示指令在多核CPU情况下,在当前处理器将缓存数据写回到系统主内存时,会引起其他CPU缓存了该内存地址的数据无效。

作用:保证线程的可见性,即一个线程对变量的更改对其他线程是可知的。

volatile+原子操作保证线程安全:线程在工作内存的赋值指令assign,传输到仓库store,最后write写入主内存,这三步操作是一个整理,中间不会中断,就好像直接操作主存一样。使用volatile后,线程对变量原子操作值被修改了,会根据缓存一致性协议通知其他线程的缓存副本过期。

volatile 线程不安全例子

*缓存一致协议(MESI协议),缓存数据cache状态:

  • M(Modified) :这行数据有效,缓存数据修改了与内存不一致,数据只存在于本Cache中。
  • E(Exclusive):这行数据有效,缓存数据和内存中的数据一致,数据只存在于本Cache中。
  • S(Shaed)    : 这行数据有效,缓存数据和内存中的数据一致,数据存在于很多Cache中。
  • I(Invalid)     : 缓存数据无效。

2个线程进行i++操作,正确结果应该i = 3。

按照原子性操作, 3、4是线程2的原子操作, 5、6、7是线程1的原子操作。但注意第5步,工作内存的缓存数据状态为I,即缓存数据无效。

这就说明,volatile修饰的变量在多线程中是线程不安全的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值