Java并发编程 之 volatile

国庆已经结束了,本该在国庆前就应该做好这篇笔记的,怎奈自己太懒,就在今天把前几天的知识梳理一下。在前几篇的博客介绍了一点并发编程的相关知识,今天我对volatile的原理简单的阐述一下。

要想理解volatile的原理,需要对JMM(Java内存模式)有些了解。

在实际的程序运行中,由于cpu执行速度很快,而从内存读取数据和向内存写入数据的过程跟cpu执行指令的速度比起来要慢的多,于是在cpu就引入了缓存。

也就是说在运行的时候主存中的数据会在缓存有一份拷贝,cpu的操作是针对这个拷贝去进行的,最后在把结果写会到主存中。


这里写图片描述

可是这样在多线程运行就有可能出现问题。比如:i=i+1;(i的初始值为1)

假设有两个A、B线程运行这个程序,一开始两个线程都分别有i这个值的拷贝存在缓存中。A先对缓存进行i+1的操作,缓存中i这时候已经是2了,然后写会到主存中,主存也是2。

但是B线程在运行在主存被刷新之前,就已经有了i的拷贝,也就是说线程B的缓存i的值还是1,而不是A线程运行完毕的2,那么这就出现了错误。

但是这里就算是用volatile来修饰这个i,程序的结果还是有可能会报错。要想用对volatile就要保证数据操作的原子性。

用volatile修饰一个变量的时候,当对该变量有写的操作,会强制将修改的值立即写入主存,它可以保证其他线程每次的读取,都是一个最新的值。

这就是volatile的可见性,可见性只能保证每次读取的是最新的值,但是volatile没办法保证对变量的操作的原子性。如i=i+1,它包括读取变量的原始值、进行加1操作、写入工作内存。就算你用volatile来修饰i也还是有可能会出错。情况和上面是一样的。

虽然A线程是把主存刷新了,发出信号,让其他拥有该变量的线程中的数据变成无效状态,当处理器对这个数据进行修改操作的时候,就会从内存中重新读取。但是B线程是在主存被刷新之前就读取了,并且已经完成了对i+1的操作,后面的操作只是对i的写回内存操作,并没有涉及到修改操作,所以这样还是保证不了数据的正确性。

所以要想用好volatile,就要保证操作的原子性。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值