专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

Java内存模型(JMM)详解

  头条创作挑战赛什么是JMM?
  在上一篇文章https:mp。weixin。qq。comsZiuZHQ8OMFudzr0jCqn1dQ中,我们了解了计算机由于各个硬件的读取速度之间的巨大差距,和充分利用CPU的性能的手段方法,及其所带来的一系列问题:为了充分压榨CPU的性能,CPU会对指令乱序执行或者语言的编译器会指令重排,让CPU一直工作不停歇,但同时会导致有序性问题。为了平衡CPU的寄存器和内存的速度差异,计算机的CPU增加了高速缓存,但同时导致了可见性问题为了平衡CPU与IO设备的速度差异,操作系统增加了进程、线程概念,以分时复用CPU,但同时导致了原子性问题。
  Java是最早尝试提供内存模型的编程语言。由于Java语言是跨平台的,另外各个操作系统总存在一些差异,Java在物理机器的基础上抽象出一个内存模型(JMM)
  JMM可以看作是Java定义的并发编程相关的一组规范,除了抽象了线程和主内存之间的关系之外,其还规定了从Java源代码到CPU可执行指令的这个转化过程要遵守哪些和并发相关的原则和规范,这样就可以屏蔽各个操作系统的差异,简化多线程编程。Java运行时内存区域与硬件内存的关系Java内存区域和Java内存模型有何区别?
  这是一个非常容易让人混淆的问题,Java内存区域和内存模型完全是不一样的东西,Java内存区域,也叫内存区域、JVM内存模型,和Java虚拟机(JVM)的运行时区域相关,是指JVM运行时将数据分区域存储,强调对内存空间的划分。
  Java内存模型,也叫内存模型(JMM),是Java定义的并发编程相关的一组规范,除了抽象了线程和主内存之间的关系之外,其还规定了从Java源代码到CPU可执行指令的这个转化过程要遵守哪些和并发相关的原则和规范,屏蔽各个操作系统的差异。
  通俗点说:JMM规范了程序中变量的访问规则,保证了操作的原子性、可见性、有序性,我们下文慢慢道来。
  我们知道JVM运行时内存区域是分区域的,分为栈、堆等,其实这些都是JVM定义的逻辑概念。但在传统的硬件内存架构中是没有栈和堆这种概念。
  其中:图中栈可以细分为:虚拟机栈(JVMStacks)和本地方法栈(NativeMethodStack)虚拟机栈(JVMStacks):线程私有,它的生命周期和线程相同,描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个线帧(StackFrame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每个方法从调用直至执行完成的过程,都对应着一个线帧在虚拟机栈中入栈到出栈的过程
  本地方法栈(NativeMethodStack):线程私有,本地方法栈与虚拟机栈的作用是一样的,只不过虚拟机栈是服务Java方法的,而本地方法栈是为虚拟机调用Native方法服务的。在Java虚拟机规范中对于本地方法栈没有特殊的要求,虚拟机可以自由的实现它,因此在SunHotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一了。
  线程开始调用本地方法时,会进入不再受JVM约束的世界。本地方法可以通过JNI(JavaNativeInterface)来访问虚拟机运行时的数据区,甚至可以调用寄存器,具有和JVM相同的能力和权限。JNI类本地方法最著名的应该是System。currentTimeMillis()堆(Heap)
  虚拟机堆是Java虚拟机中内存最大的一块,是被所有线程共享的,在虚拟机启动时候创建,Java堆唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,随着JIT编译器的发展和逃逸分析技术的逐渐成熟,栈上分配、标量替换优化的技术将会导致一些微妙的变化,所有的对象都分配在堆上渐渐变得不那么绝对了。
  更多精彩文章在公众号小牛呼噜噜
  Java中栈和堆既存在于计算机的高速缓存中,又存在于主存中,所以两者并没有很直接的关系。Java线程与主内存的关系
  Java内存模型(JMM)抽象了线程和主内存之间的关系,就比如说线程之间的共享变量必须存储在主内存中。在JDK1。2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。
  而在当前的Java内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。什么是主内存?什么是本地内存?主内存:所有线程创建的实例对象都存放在主内存中,不管该实例对象是成员变量还是方法中的本地变量(也称局部变量)本地内存:每个线程都有一个私有的本地内存来存储共享变量的副本,并且,每个线程只能访问自己的本地内存,无法访问其他线程的本地内存。本地内存是JMM抽象出来的一个概念,存储了主内存中的共享变量副本。
  Java内存模型其实是一种规范,定义了很多东西:所有的变量都存储在主内存(MainMemory)中。每个线程都有一个私有的本地内存(LocalMemory),本地内存中存储了该线程以读写共享变量的拷贝副本。线程对变量的所有操作都必须在本地内存中进行,而不能直接读写主内存。不同的线程之间无法直接访问对方本地内存中的变量。
  这里所讲的主内存、工作内存与Java内存区域中的Java堆、栈、方法区等并不是同一个层次的内存划分,这两者基本上是没有关系的,如果两者一定要勉强对应起来,那从变量、主内存、工作内存的定义来看,主内存主要对应于Java堆中的对象实例数据部分,而工作内存则对应于虚拟机栈中的部分区域。线程间通信
  线程间的通信一般有两种方式进行,一是通过消息传递,二是共享内存。Java线程间的通信采用的是共享内存方式,JMM为共享变量提供了线程间的保障。如果两个线程都对一个共享变量进行操作,共享变量初始值为1,每个线程都变量进行加1,预期共享变量的值为3。在JMM规范下会有一系列的操作。我们直接来看下图:
  在多线程的情况下,对主内存中的共享变量进行操作可能发生线程安全问题,比如:线程1和线程2同时对同一个共享变量进行操作,执行1操作,线程1、线程2读取的共享变量是否是彼此修改前还是修改后的值呢,这个是无法确定的,这种情况和CPU的高速缓存与内存之间的问题非常相似
  如何实现主内存与工作内存的变量同步,为了更好的控制主内存和本地内存的交互,Java内存模型定义了八种操作来实现:lock:锁定。作用于主内存的变量,把一个变量标识为一条线程独占状态。unlock:解锁。作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。read:读取。作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用load:载入。作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。工作内存即本地内存。use:使用。作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。assign:赋值。作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。store:存储。作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。write:写入。作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中。重温Java并发三大特性原子性
  原子性:即一个或者多个操作作为一个整体,要么全部执行,要么都不执行,并且操作在执行过程中不会被线程调度机制打断;而且这种操作一旦开始,就一直运行到结束,中间不会有任何上下文切换(contextswitch)比如:inti0;语句1,原子性i;语句2,非原子性
  语句1大家一幕了然,语句2却许多人容易犯迷糊,i其实可以分为3步:i被从局部变量表(内存)取出,压入操作栈(寄存器),操作栈中自增使用栈顶值更新局部变量表(寄存器更新写入内存)
  执行上述3个步骤的时候是可以进行线程切换的,或者说是可以被另其他线程的这3步打断的,因此语句2不是一个原子性操作
  更多精彩文章在公众号小牛呼噜噜
  在Java中,可以借助synchronized、各种Lock以及各种原子类实现原子性。synchronized和各种Lock是通过保证任一时刻只有一个线程访问该代码块,因此可以保证其原子性。各种原子类是利用CAS(compareandswap)操作(可能也会用到volatile或者final关键字)来保证原子操作。可见性
  可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值。我们来看一个例子:publicclassVisibilityTest{privatebooleanflagtrue;publicvoidchange(){flagfalse;System。out。println(Thread。currentThread()。getName(),已修改flagfalse);}publicvoidload(){System。out。println(Thread。currentThread()。getName(),开始执行。。。。。);inti0;while(flag){i;}System。out。println(Thread。currentThread()。getName(),结束循环);}publicstaticvoidmain(String〔〕args)throwsInterruptedException{VisibilityTesttestnewVisibilityTest();线程threadA模拟数据加载场景ThreadthreadAnewThread(()test。load(),threadA);threadA。start();让threadA执行一会儿Thread。sleep(1000);线程threadB修改共享变量flagThreadthreadBnewThread(()test。change(),threadB);threadB。start();}}
  threadA负责循环,threadB负责修改共享变量flag,如果flagfalse时,threadA会结束循环,但是上面的例子会死循环。原因是threadA无法立即读取到共享变量flag修改后的值。我们只需privatevolatilebooleanflagtrue;加上volatile关键字threadA就可以立即退出循环了。
  Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。
  因此,可以使用volatile来保证多线程操作时变量的可见性。除了volatile,Java中的synchronized和final两个关键字以及各种Lock也可以实现可见性。有序性
  有序性:即程序执行的顺序按照代码的先后顺序执行。inti0;intj0;i10;语句1j1;语句2
  但由于指令重排序问题,代码的执行顺序未必就是编写代码时候的顺序。语句可能的执行顺序如下:语句1语句2语句2语句1
  指令重排对于非原子性的操作,在不影响最终结果的情况下,其拆分成的原子操作可能会被重新排列执行顺序。指令重排不会影响单线程的执行结果,但是会影响多线程并发执行的结果正确性。在Java中,可以通过volatile关键字来禁止指令进行重排序优化,
  详情可见:https:mp。weixin。qq。coms6GGV0YDwTFW4VcLRYfBAg
  也可以使用synchronized关键字保证同一时刻只允许一条线程访问程序块。
  参考资料:
  《java并发编程实战》
  https:www。cnblogs。comczwbigp11127124。html
  本篇文章到这里就结束啦,如果我的文章对你有所帮助,还请帮忙一键三连:点赞、关注、收藏,你的支持会激励我输出更高质量的文章,感谢!
  计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章,首发于公众号小牛呼噜噜,我们下期再见!

科莫多巨蜥的毒液到底有多可怕?2009年,一名31岁的渔民安瓦尔,在印尼科莫多岛上采摘水果,结果不小心从水果树上掉了下来,刚好踩到了一只巨型蜥蜴,蜥蜴瞬间就朝他扑了过去,咬住了他的腿,之后又咬住了他的手臂,身体武汉未来的房价会涨到100000元平米吗?这个问题的答案是肯定的!以目前的趋势,未来武汉房价必然达到10万的水平,只是时间长短的问题。2010年至2017年,短短七年间,武汉的房价已经翻了3番,目前,武汉部分高端楼盘如洞庭兰州青白石片区,中央公园怎么样?兰州北拓的黄金区域,目前基础交通还跟不上建设需要,交通滞后可能会成为十四五期间兰州青白石片区发展的的最大障碍!不过就兰州地理位置和城区格局而言,青白石片区是离主城区最近的待开发区域农民为什么不在国家统计失业范围之内?中国有四个儿子,大儿子叫工人,二儿子叫子弟兵,三儿子叫公务员,四儿子叫农民,所以四儿子就没有纳入统计失业包括养老金范围,因为四儿子有金山银山还有三分地。农民有土地,这是农民可以赖以农村成立社区是什么意思?很多农村驻有村委会办公室,同时也驻有社区管理委员会办公室,特别是在城市郊区的农村和街道的农村都同时设立了村委会和社区管理委员会,很多人弄不明白是怎么回事。那农村成立社区是什么意思呢农村里的剩男,为何一剩再剩呢?到底是什么原因?男女比例失调。计划生育只要一个孩子时,受封建思想影响,都拚命要男孩,等他们长大了,很难找到媳妇。一,农村姑娘远嫁,二,女孩见少,三,彩礼高,四,剩男挣钱少。我就一大龄剩男!个人亲身抖音付费直播试水,看直播要给钱了?我们应该如何思考?使劲收,最好是家人们看的话,一分钟100块钱。毕竟粉丝听话的很。毕竟人设都设计好了打PK,卖货摆错价格,怒亏2个亿回馈粉丝。没事就怼工厂,怼员工反正就是赔钱回馈粉丝。赔完还得补交税马上就要退休了,退休工资才3650元太少了,怎么办?3600不少了。我企业工龄32年,退休时退休金只有2200,涨了这么多年还不到3000。知足常乐吧!如果身体不好,这些钱也够生活了,如果身体还可以,就找一些力所能及的工作,打打工补南宁五象新区未来的发展潜力很大吗?五象新区无法成为国家级新区!!!目前看来,五象新区的潜力也就这样了。我们对比一下贵阳的贵安新区,贵安新区的面积是1700平方公里,由贵阳市的郊区和安顺市合并得来。是全国第8个国家级如果把三峡大坝加高10米,截留更多的洪水,可行吗?我国的三峡大坝,作为当今世界上最大的水利枢纽工程,位于湖北省宜昌市上游,距下游葛洲坝水电站38公里,三峡大坝全长2309米高185米,呈梯形形状,集发电旅游航运调控洪水于一身。三峡大家有经历过亲人去世吗?是怎样走出痛苦和想念的?2018年9月1日下午3点8分,我的妻子在医院里停止了呼吸。她的眼睛没有闭上,我流着泪,帮她合上了双眼。我永远失去了我最亲近的爱人,孩子永远的失去了妈妈。一位好妻子,好女儿,好姑妈
苏宁张康阳在香港败诉脉脉CEO再回应评论真实性商业参考NEWS今日要闻苏宁少东家张康阳在香港败诉脉脉CEO再回应评论真实性福特计划在未来几周内减员多达8000人保时捷将推出纯电动跨界车奈飞计划未来在内容投入170亿美元马斯克脑机接口公山西大学在各省最低录取线大幅上升各省最低投档线正陆续公布!截止今日,已逾半数省份公布了各高校最低投档线。双一流新贵曾经的国立第三大学120岁的老牌名校山西大学,在已公布的省份中,山西大学最低投档线分数均比20213人,山西省委研究拟任职干部公示最新官宣,晋团融媒聚焦。省委组织部公示(公示时间7月22日至28日)省委研究拟任职干部邢利民,男,汉族,1972年5月生,在职研究生,中共党员,现任省商务厅党组成员副厅长,拟任省直山西警界新动向多名市级公安局长转任省属高校副校长2022年7月中旬,史水鸿调任山西大同大学副校长。在此之前,他的职务是大同市副市长市公安局局长。史水鸿是山西新绛人,生于1966年,在山西省公安厅太原市公安局大同市公安局工作了整整从孝庄秘史到甄嬛传带你感受清朝选秀女真正的流程在电影和电视剧中,凡是涉及清宫剧必然要提及选秀女这个万恶的制度。究竟这个制度怎么来的?哪些女孩可以参加海选?秀女选拔的流程是怎样的?在选秀过程中又会遭遇哪些禁忌?今天白羽就跟大家好为什么肠道容易长息肉?肠内若有息肉,身体会有什么症状?随着医疗技术的进步,人们对自己身体的认知也越来越清晰,尤其是内窥镜的诞生,让我们可以进一步了解体内的状态,从而发现一些之前无法观察到的变化。近期由于单位组织体检,河南的王先生来到了暴雨预警!今天傍晚起山东11市有大到暴雨局部大暴雨记者于民星22日08时,山东省气象台发布暴雨蓝色预警受气旋影响,预计22日傍晚至23日上午,我省自西向东有一次明显降雨过程,并伴有雷电。全省过程平均降水量3050毫米(图1),其中体内有癌,从指甲能看出来?指甲长成3种样子,可能是癌症在走近女性朋友大多爱美,平时喜欢晒照片,和网友分享自己的生活,本来是一个不经意的举动,没想到无意中救了自己一命,而且病魔还躲在令人想不到又容易忽视的地方。在社交平台晒出自己的美甲照片,网夺去赵忠祥生命鳞状细胞癌是啥?全身都会长,主要3个特征要小心赵忠祥老师是央视的著名主持人,老一辈人对赵忠祥老师印象深刻,很多年轻一辈的童年也少不了赵忠祥老师在动物世界人与自然中主持的温柔亲切的声音。但这位家喻户晓的央视主持人在78岁的年纪不2015年,辽宁女孩放弃1000万嫁妆下海创业,4年时间大赚1个亿文猩猩科普编辑猩猩科普前言辽宁女孩放弃1000万嫁妆,和家人决裂独自创业,她能把没人要的边角料转手卖1700万高价,只用4年时间便赶超无数同行大佬,自己身价也达到了1个亿!到底是什深度中国男篮输球的偶然因素,提高身体对抗能力才是王道中国男篮输球虽然有偶然因素,但从全场看也是应该的。黎巴嫩虽然没有高大中锋,但球员技术熟练,投篮准确,身体强壮。整个球队运转流畅,典型的现代篮球风格。而我们就像一台破老爷车,打起球来
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网