我们都知道volatile具有两个功能:
1.禁止指令重排序;
2.保证所修饰变量修改后的内存可见性;
想必大家在网上搜索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步是立即执行的,从而保证了其修饰变量修改的内存可见性。
关于volatile关键字是否具有原子性例子的正确解释
最新推荐文章于 2022-10-12 22:53:19 发布