首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

并发编程——为什么volatile变量+操作线程不安全

学习volatile的时候也许我们会看到下面这句话:

对于volatile变量来说,自增操作线程不安全。

那为什么不安全呢?本帅博主看的是《并发编程的艺术》这本书,这本书对这一事件也没有做出很让人易懂的解释。那么我们自己用例子来测试一下咯~

测试代码如下:

在上面这个代码中,VolatileExample类汇总声明了一个volatile变量v,以及三个方法,set()、get()和用来进行自增操作的getAndIncrement()方法。

在主函数中,我创建了两个线程,各自循环调用VolatileExample类的实例volatileExample中的getAndIncrement()方法100000次。

如果volatile保证++安全,那么执行结果将是200000.

那么真实结果是多少呢?

多执行几次:

从上面几次的执行结果我们可以看到,始终都不到200000万。这样的结果表明volatile不保证volatile++这样的操作具有原子性。

为什么呢?

其实很简单,因为“++”属于复合操作。

上面的VolatileExample其实等价于一下的代码:

如果不清晰的话,我们可以通过javap反编译一下。

使用javap对VolatileExample类进行反编译,出来的结果如下:

我们可以看到,getAndIncrement()方法中的v++语句被编译成了 七条语句,这属于复合操作。

v++其实相当于:

读v

对v+1;

将原来的v值置为v+1。

volatile保证可见性,当进行++操作的时候,volatile保证第一条指令正确,即读正确。当执行接下来的指令的时候,其他线程可能对v加大了,当将v存回去的时候(即执行putfield指令的时候),可能将一个更小的v同步回主内存去了。所以最终得到的数字就会小于200000.

总结:volatile的读写具有原子性,但是自增操作属于复合操作,因此不具有原子性,所以线程也不安全。

好啦,以上就是关于volatile变量自增是否线程安全的相关知识总结。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190103G0V3DW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券