当前位置:首页 > Java技术 > JVM知识(三):内存模型和可见性

JVM知识(三):内存模型和可见性

2022年08月05日 19:36:24Java技术6

这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况。来聊聊java线程对一个变量的更新怎么通知另一个线程,及volatile的作用和指令重排序的问题。

内存模型

  首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做呢,又或者说,一个java线程对一个变量的更新怎么通知到另外一个线程呢?我们知道java当中的实例对象、数组元素都放在java堆中,java堆是共享的(这里我们把java堆称为主内存)。而每一个线程都是自己私有的内存空间(称为工作内存),如果线程1要向线程2通信,一定会经过以下类似的流程:

  JVM知识(三):内存模型和可见性 _ JavaClub全栈架构师技术笔记  

  1、线程1将自己工作内存中的X更新为1并刷新到主内存中;

  2、线程2从主内存中读取变量X=1,更新到自己的工作内存中,从而线程2读取的X就是线程1更新后的值。

从上面的流程看出线程之间的通信都需要经过主内存,而主内存与工作内存的交互,则需要java内存模型(JMM)来管理。下图演示了JMM如何管理主内存和工作内存:

JVM知识(三):内存模型和可见性 _ JavaClub全栈架构师技术笔记

当线程1需要将一个更新后的变量值刷新到主内存中时,需要经过两个步骤:

  1、工作内存执行store操作(存储操作);

  2、主内存执行write操作(写操作);

完成这两个操作即可将工作内存中的变量值刷新到主内存中,即线程1工作内存和主内存的变量值保持一致;

当线程2需要从主内存中读取变量的最新值时,同样需要经过两个步骤:

  1、主内存执行read操作,将变量值从主内存中读取出来;

  2、工作内存执行load操作,将读取出来的变量值更新到本地内存的副本;

完成这两步,线程2的变量和主内存的变量值就保持一致了。

可见性

  java中有一个关键字 volatile,它有什么用呢?(没有volatile会出现的情况举例!

  这个答案其实就在上面说java线程间通信机制中,我们想象一下,由于工作内存这个中间层的出现,线程1和线程2比如存在延迟的问题,例如线程1在工作内存中更新了变了,但是还没有刷新到主内存,而此时线程2获取到的变量值就是还未更新的变量值,又或者线程1成功将变量更新到主内存,但是线程2依然使用主键工作内存中的变量值,同样会出现问题。不管出现哪种情况都可能导致线程间的同学不能达到预期的目的。

//线程1 
boolean stop = false; while(!stop){ doSomething(); }
//线程2 stop = true;

  这个例子表示线程2通过修改stop的值,来控制线程1的中断,但是在真是环境中可能会出现意想不到的结果,线程2在执行之后,线程1并没有立刻中断甚至一直不会中断。出现这种情况的原因就是线程2对线程1的变量更新无法第一时间获取到。

但是这一些等到volatile出现后,就不会出现了。volatile保证两件事情:

  1、线程1工作内存中的变量更新会强制立即写入到主内存;

  2、线程2工作内存中的变量会强制立即失效,这使得线程2必须去住线程中获取最新的变量值。

所以这就理解了volatile保证了变量的可见性。因为线程1对变量的修改能第一时间让线程2可见。 

作者:MoreThinking
来源链接:https://www.cnblogs.com/MoreThinking/p/9884561.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/18120.html

分享给朋友:

“JVM知识(三):内存模型和可见性” 的相关文章

OpenWrite技术自媒体界的JVM一次编辑、随处发布

OpenWrite技术自媒体界的JVM一次编辑、随处发布

原文 :https://mp.weixin.qq.com/s/KUtJ2dwhBRuJ2G_-PkQFEA 最懂你的科技自媒体管理平台 【实用小工具推荐】给科技或技术同学们推荐一款比较好用的工具,可以实现一稿多发,主流的技术渠道基本涵...

[JVM教程与调优] 为什么要学习JVM虚拟机?

[JVM教程与调优] 为什么要学习JVM虚拟机?

JVM在我们开发阶段不会用到,但是到了生产环境中,那么就会变得非常重要了。 为什么这么说呢? 一方面,因为我们的生产环境是比较复杂的。各种可能的问题都会出现,比如说:硬盘坏了、网络坏了、CPU利用率高了等问题层次不穷。 另外一方面,在我们生产环境出现问题,还不好进行定位。因为没...

JVM中有哪些垃圾收集器?

写在前面 本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见100个问题搞定Java虚拟机 解答 新生代垃圾...

JVM内存模型及垃圾收集策略解析

JVM内存模型及垃圾收集策略解析

JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍过JVM分代垃圾回收策略的基础概念,现在很多编程语言都引入了类似Java JVM的内存模型和垃圾收集器的机制,下面我们将主要针对Java中的JVM内存模型及垃圾收集的具体策略进行综合的分析。 一 JVM内存模型...

jvm优化——运行参数篇

jvm优化——运行参数篇

在这篇文章中主要介绍jvm的一些运行参数 对jvm优化总结篇可以阅读:JVM优化——总结篇 1、jvm的运行参数 1.1、三种参数类型 jvm的参数类型分为三种,分别是: 1、标准参数: 标准参数的意思是说一般比较稳定,在以后jvm的版...

JVM学习1--数字存储,内存模型,指令重排

JVM学习1--数字存储,内存模型,指令重排

一、数字在计算机中的存储   整数:以补码形式存储。     补码:正数的补码是自身,负数的补码是取反码加1(取反码时符号位还是1)   浮点型:以float类型表示            注意一下,这八位指数实际上是(127...

深入理解JVM—JVM内存模型

深入理解JVM—JVM内存模型

原文地址:http://yhjhappy234.blog.163.com/blog/static/316328322011101723933875/?suggestedreading&wumii 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁...

JVM——JVM大厂面试问题与解答

JVM——JVM大厂面试问题与解答

摘要 本博文主要分享在JVM中的大厂面试问题。总结相关面试问题与yu解答。帮助大家更好的学习与理解JVM的原理。同时也是分享一些有关于JVM实战的经验,帮助大家在工作中排查错误。 一、JVM的内存模型 1.1 JVM1.8内存模型 1.2 JVM内存模型中...

jvm性能调优实战 - 31从测试到上线

jvm性能调优实战 - 31从测试到上线

文章目录 Pre 开发好系统之后的预估性优化 系统压测时的JVM优化 对线上系统进行JVM监控 Pre 前面两篇文章,已经给大家介绍...

JVM学习笔记1:Java虚拟机内存模型

JVM学习笔记1:Java虚拟机内存模型

JVM学习笔记1:Java虚拟机内存模型 学习JVM,Java虚拟机对理解Java程序执行过程和Java程序性能调优具有很大帮助。本系列博客旨在由浅到深学习并理解JVM。参考阅读:《深入理解Java虚拟机-JVM高级特性和最佳实践》。这个书写的非常好,推荐有条件的读者买一本来阅读...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。