volatile可以保证可见性,那么多线程情况下,线程们也总是可以从主存中拿到最新的值,那为什么还是线程不安全?哪里出了问题?
我再把问题细化一下:首先i++不是原子操作。他分成三个部分,我简称其为S1,S2,S3。
S1:线程将i的值从主存中加载至cache
S2:CPU从cache中获取i的值并计算
S3:线程将计算好的i的值从cache写入主存
那么在没有添加volatile时,显然i++是不安全的。例如线程T1,T2,分将i从0加到1准备写入主存的时候,可能T1线程先写入了,但是T2线程不知道,也写入了,会造成写覆盖,所以线程不安全。
但是加了volatile之后,情况会有些许变化。volatile保证可见性,意味着,在上边的例子中,当T1成功写入的时候,由于缓存一致性协议,T2会立刻知道主存已经被修改,同时自己的缓存已经失效。所以T2会从主存中重新加载更新后的数据。那么既然T2已经拿到新的数据了,于是T2去重新执行i++,照此来说,就应该是线程安全的了。请问哪里出了问题?
全部评论
(4) 回帖