下图描绘了该情况 。在左CPU上运行的一个线程将共享对象复制到其CPU缓存中,并将其count变量更改为2.对于在右边的CPU上运行的其他线程 , 此更改不可见,因为计数更新尚未刷新回主内存中.

文章插图
图片
要解决此问题,您可以使用Java的volatile关键字 。volatile关键字可以确保直接从主内存读取给定变量,并在更新时始终写回主内存 。
JMM与硬件内存连接 - 竞态条件如果两个或多个线程共享一个对象,并且多个线程更新该共享对象中的变量,则可能会出现竞态 。
想象一下 , 如果线程A将共享对象的变量计数读入其CPU缓存中 。想象一下,线程B也做同样的事情,但是进入不同的CPU缓存 。现在,线程A将一个添加到count,而线程B执行相同的操作 。现在var1已经增加了两次,每个CPU缓存一次 。
如果这些增量是按先后顺序执行的 , 则变量计数将增加两次并将原始值+ 2写回主存储器 。
但是,两个增量同时执行而没有适当的同步 。无论线程A和B中哪一个将其更新后的计数版本写回主存储器,更新的值将仅比原始值高1,尽管有两个增量 。
该图说明了如上所述的竞争条件问题的发生:

文章插图
图片
要解决此问题,您可以使用Java synchronized块 。同步块保证在任何给定时间只有一个线程可以进入代码的给定关键部分 。同步块还保证在同步块内访问的所有变量都将从主存储器中读入 , 当线程退出同步块时,所有更新的变量将再次刷新回主存储器,无论变量是不是声明为volatile
推荐阅读
- 一文读懂Kubernetes部署策略
- 如何降低小米手机发热的概率?一文带你了解
- 一文了解托管在亚马逊云科技的向量数据库MyScale
- 一文教你学会使用Nginx
- 一文了解Redis的持久化
- 一文聊聊如何快速监控 Oracle 数据库
- 一文带你掌握Containerd
- 一文了解TikTok店铺类型,美国本土店VS跨境店有什么区别?如何入驻?
- 想要搞定一个女人,只需在这四个方面用力就行,能轻松让她“动情
- 搞定流畅性过后,安卓旗舰手机游戏体验还要什么?
