关于volatile关键字是否具有原子性例子的正确解释

我们都知道volatile具有两个功能:
1.禁止指令重排序;
2.保证所修饰变量修改后的内存可见性;

想必大家在网上搜索volatile关键字都看过下面这个例子:
解释volatile是否具有原子性
对于这个例子,原博客上的解释是:
假如某个时刻变量inc的值为10,
  线程1对变量进行自增操作,线程1先读取了变量inc的原始值,然后线程1被阻塞了;
  然后线程2对变量进行自增操作,线程2也去读取变量inc的原始值,由于线程1只是对变量inc进行读取操作,而没有对变量进行修改操作,所以不会导致线程2的工作内存中缓存变量inc的缓存行无效,所以线程2会直接去主存读取inc的值,发现inc的值时10,然后进行加1操作,并把11写入工作内存,最后写入主存。
  然后线程1接着进行加1操作,由于已经读取了inc的值,注意此时在线程1的工作内存中inc的值仍然为10,所以线程1对inc进行加1操作后inc的值为11,然后将11写入工作内存,最后写入主存。
  那么两个线程分别进行了一次自增操作后,inc只增加了1。
  
我读完这段解释后很是不解,为啥线程2修改完变量值后,不会把线程1中缓存的值至为无效呢。后来在其他评论中看到这样一个解释,我觉得可以合理地解释这个例子。
首先每个线程将inc自增后写回主内存可以分为以下几步:
1.从主内存中获取到inc变量的值;
2.在寄存器中进行inc=inc+1的计算;
3.将计算后的值置入cpu的高速缓存中,即t=inc;
4.将缓存中的值写入主内存;
假设有如下的情况发生:
某个时刻变量inc的值为10;
线程1在执行完第2步自增时,还没开始第3步操作时即缓存中inc的值还是10,线程被挂起。线程2开始按以上步骤执行完成inc变量的自增,并写入内存。此时inc值变为11,但却进行了两次自增操作;
volatile保证第3、4步是立即执行的,从而保证了其修饰变量修改的内存可见性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值