当前位置: 首页 > 后端技术 > Java

并发编程volatile与JMM多线程内存模型

时间:2023-04-01 22:47:16 Java

1.通过程序看现象在开始为大家讲解Java多线程缓存模型之前,我们先来看下面的代码。这段代码的逻辑很简单:主线程启动了两个子线程,一个线程1,一个线程2,线程1先执行,线程2休眠2秒后执行。这两个线程使用一个初始值为false的共享变量shareFlag。如果shareFlag一直等于false,线程1就会一直处于死循环中,所以我们在线程2中将shareFlag设置为true。公共类VolatileTest{publicstaticbooleanshareFlag=false;publicstaticvoidmain(String[]args)throwsInterruptedException{newThread(()->{System.out.print("startthread1=>");while(!shareFlag){//shareFlag=false,然后是无限循环//System.out.println("shareFlag="+shareFlag);}System.out.print("线程1执行完成=>");}).start();线程.睡眠(2000);newThread(()->{System.out.print("开始执行线程2=>");shareFlag=true;System.out.print("线程2执行完成=>");}).start();}}如果你还没有学过JMM线程模型,可以看看上面的代码,预期输出如下:开始执行线程1=>开始执行线程2=>线程2执行完成=>线程1执行完成=>如下图,正常人理解这段代码,先执行线程1进入循环,线程2修改shareFlag=true,线程1跳出循环。所以跳出循环的线程1会打印“线程1执行完成=>”,但是经过笔者的实验,不会打印“线程1执行完成=>”,线程1也不会跳出无限环形。为什么是这样?2、为什么会出现这种现象(JMM模型)?为了解释上面提到的问题,我们需要学习JMM(JavaMemoryModel)Java内存模型。我觉得叫它Java多线程内存模型更准确。首先,在JMM中,每个线程都有自己的工作内存。当程序启动时,线程将共享变量加载(read&load)到它自己的工作内存中。加载到线程工作内存中的内存变量是主内存中的共享变量。的副本。也就是说此时内存中有三份shareFlag,值都等于false。当线程2执行到shareFlag=true时,修改自己的workingmemorycopy为shareFlag=true,同时将copy的值同步回写(store&write)到主存。但是线程1的工作内存中的shareFlag=false没有改变,所以线程1一直在死循环。3.MESI缓存一致性协议根据上面的实验和JMM模型,线程2修改的共享变量的值是线程1感知不到的,那么线程1怎么感知到共享变量的值发生了变化呢?其实也很简单,在shareFlag共享变量中加上volatile关键字即可。publicvolatilestaticbooleanshareFlag=false;底层原理是这样的,加上volatile关键字提示JMM遵循MESI缓存一致性协议,其中包括以下缓存使用规范(不懂的可以忽略,后面会用简单的语言和例子)。Modified:表示当前Cache行的数据被修改(Dirty),只在当前CPU的Cache中被修改;此时Cacheline的数据和其他Cache中的数据不一样,内存中line的数据也不一样。Exclusive:代表当前Cacheline的数据为有效数据,其他CPU的cache中没有该行数据;并且当前的Cacheline数据和内存中的数据是一样的。Shared:这行数据缓存在多个CPU的Cache中,Cache中的数据与内存中的数据是一致的;Invalid:表示当前Cacheline中的数据无效;上面的缓存使用规范可能过于复杂和简单了,也就是说,当线程2修改shareFlag(参考Modify)时,通知总线我修改了共享变量shareFlag,线程1监听Bus。shareFlag的副本被删除以使其无效。当线程1需要再次使用shareFlag时,发现工作内存中没有shareFlag变量的副本,就会从主内存中重新加载(read&load)。注明出处(一定要有链接,不能只是文字):字母哥博客-zimug.com如果觉得对你有帮助,请点赞分享!您的支持是我创作不竭的动力!.另外,作者近期输出了以下优质内容,期待大家的关注。《kafka修炼之道》《手摸手教你学Spring Boot2.0》《Spring Security-JWT-OAuth2一本通》《实战前后端分离RBAC权限管理系统》《实战SpringCloud微服务从青铜到王者》

猜你喜欢