为什么volatile关键字不能保证变量是线程安全的

当一个变量定义为volatile后,该变量对所有线程均可见。即当一条线程修改了这个变量的值,新值对于其他线程可以是立即得知的。但是这并不意味着volatile变量在并发下是线程安全的。这是因为volatile只保证当前线程在读取这个变量时,变量的值与其他所有线程一致。当前线程把读取到的一致的(在读的时候一致)值压入栈顶进行计算时,由于该计算可能不具备原子性。在执行该计算的各个字节码时,变量可能被其他线程改变。而这个改变并不会影响当前线程已压入栈顶的数据,这时栈顶的数据就成了过期的数据,从而发生线程安全问题。
所以,在不符合以下两条规则的运算场景中,我们仍然要通过加锁来保证原子性。

  • 运算结果不依赖于变量的当前值,或者能够确保只有单一的线程修改变量的值
  • 变量不需要与其他的状态变量共同参与不变约束

注:除了保持变量的可见性外,volatile关键字还有另一层语义:禁止指令重排序优化。

详见《深入理解java虚拟机》12.3.3节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值