volatile 和 内存屏障

匿名 (未验证) 提交于 2019-12-02 23:52:01

volatile

  • OpenJDKunsafe.cppvolatilelock:
  • LockLockLockCPUCPULock
  • CPU里缓存了该地址的数据无效


Thread-A与Threab-B同时操作主存中的一个volatile变量i时,Thread-Ai

  • Thread-A发出LOCK#指令
  • LOCK#指令锁总线(或锁缓存行)CPU不能访问总线,不能访问总线就意味着不能访问系统内存)Thread-B高速缓存中的
  • Thread-A向主存回写最新修改的i

Thread-B读取变量i,那么:

  • Thread-B发现对应地址的

volatile关键字的读和普通变量的读取相比基本没差别,差别主要还是在变量的写操作上。


为什么static volatile int i = 0; i++;不保证线程安全?

i++并不是一个原子操作i++本身特质决定的

1、获取i
2、i自增
3、回写i

A、B两个线程同时自增i
由于volatile可见性,因此步骤1ii
2步开始就有问题了,有可能出现的场景是线程A自增了i并回写,但是线程B此时已经拿到了i,不会再去拿线程A回写的i,因此对原值进行了一次自增并回写

A对i进行自增了以后cpu缓存不是应该通知其他缓存,并且重新load i么?

A对i进行了自增,线程B已经拿到了i并不存在需要再次读取i的场景,当然是不会重新load i这个值的。

ps:也就是线程B的缓存行内容的确会失效。但是此时线程B中i的值已经运行在加法指令中,不存在需要再次从缓存行读取i的场景。


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!