栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程的内存不可见性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程的内存不可见性

内存不可见性

所谓内存不可见性,就是线程对某个共享变量在线程自己的缓冲中存在副本的时候对主内存中共享变量的值是不可见的,看不见主存中的值。

如图是一个2CPU的架构系统,每个CPU都有自己的控制器和运算器,每个CPU也有自己的一级缓存,在图中的架构中,这两个CPU核心共享一个二级缓存。

假设某个时刻,这两个CPU核心分别运行着两个线程A和线程B,都要去同时访问主存中的一个共享变量x

线程操作一个共享变量时,它首先从主存中拉取并复制一份变量放置到自己的工作内存中,然后在工作内存中对变量进行修改,处理完之后将工作内存中的值重新写回到主存中。

初始状态,两级缓存都为空, x=0,假设A先执行,首先会在A的L1 Cache中查询变量x, 发现没有命中,再去查询L2 Cache,也没有命中,进而到主存中查询x,查询到x的变量后,将x的值复制到一级和二级缓存中.然后A对x加一,使得x=1,之后,刷新主存数据x=1.到目前一切正常,然后B开始运行,同样查询L1 Cache没有命中,查询L2 Cache, 命中,x = 1,没有任何问题,B现在也对x加一,使得x=2,然后更新缓存,B的L1 Cache与共享的L2 Cache与主存中的x均为2.到目前,也是一切正常,但如果现在A在L1 Cache缓存失效之前再次使用x时,首先查询A的L1 Cache,立即命中x, 此时x=1,再次进行加一操作,得到x = 2,重新更新x的信息,之后,主存,L2 Cache中的x均为2,但是按照逻辑, x被操作了3次,正确的值应该为3,但是实际结果是2,这就丢失了操作了,这就是内存不可见带来的问题。

在java中,使用volatile关键字修饰共享变量可以解决这个问题,怎么解决的呢?

既然我们知道造成上述问题的原因是线程对共享变量在主存的值不可见,那么我们就让线程在访问共享变量时,不从本地的工作内存中查,直接从主存中拉取最新的值即可。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/631612.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号