为什么会有JMM?从0到1一次性说清楚

这篇具有很好参考价值的文章主要介绍了为什么会有JMM?从0到1一次性说清楚。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JMM(Java Memory Model)是一种规范,定义了在多线程环境下Java程序中的内存访问行为。JMM保证了在多线程环境下程序的正确性,同时也允许编译器和处理器对指令进行优化,以提高程序的性能。

Java线程之间的通信由Java内存模型(简称JMM)控制,从抽象的⻆度来说,JMM定义了线程和主内存之间的抽象关系。JMM的抽象示意图如图所示:

为什么会有JMM?从0到1一次性说清楚

 对于每⼀个线程来说,栈都是私有的,⽽堆是共有的。也就是说在栈中的变量(局部变量、⽅法定义参数、异常处理器参数)不会在线程之间共享,也就不会有内存可⻅性的问题,也不受内存模型的影响。⽽在堆中的变量是共享的,称为共享变量

所以,内存可⻅性是针对的共享变量

既然堆是共享的,为什么在堆中会有内存不可⻅问题?

这是因为现代计算机为了⾼效,往往会在⾼速缓存区中缓存共享变量,因为cpu访问缓存区⽐访问内存要快得多。

线程之间的共享变量存在主内存中,每个线程都有⼀个私有的本地内存,存储了该线程以读、写共享变量的副本。本地内存是Java内存模型的⼀个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器等。

Java线程之间的通信由Java内存模型(简称JMM)控制,从抽象的⻆度来说,JMM定义了线程和主内存之间的抽象关系。JMM的抽象示意图如图所示:

为什么会有JMM?从0到1一次性说清楚

 从图中可以看出:
1. 所有的共享变量都存在主内存中。
2. 每个线程都保存了⼀份该线程使⽤到的共享变量的副本。
3. 如果线程A与线程B之间要通信的话,必须经历下⾯2个步骤:

i. 线程A将本地内存A中更新过的共享变量刷新到主内存中去。
ii. 线程B到主内存中去读取线程A之前已经更新过的共享变量。

所以,线程A⽆法直接访问线程B的⼯作内存,线程间通信必须经过主内存。

注意,根据JMM的规定,线程对共享变量的所有操作都必须在⾃⼰的本地内存中进⾏,不能直接从主内存中读取。

那么怎么知道这个共享变量的被其他线程更新了呢?这就是JMM的功劳了,也是JMM存在的必要性之⼀。JMM通过控制主内存与每个线程的本地内存之间的交互,来提供内存可⻅性保证。

Java中的volatile关键字可以保证多线程操作共享变量的可⻅性以及禁⽌指令重排序,synchronized关键字不仅保证可⻅性,同时也保证了原⼦性(互斥性)。在更底层,JMM通过内存屏障来实现内存的可⻅性以及禁⽌重排序。为了程序员的⽅便理解,提出了happens-before,它更加的简单易懂,从⽽避免了程序员为了理解内存可⻅性⽽去学习复杂的重排序规则以及这些规则的具体实现⽅法。

happens-before 谈谈 JMM的happens-before_众乐乐_2016的博客-CSDN博客  

JMM与Java内存区域划分的区别与联系

上⾯两⼩节分别提到了JMM和Java运⾏时内存区域的划分,这两者既有差别⼜有联系:

区别:两者是不同的概念层次。JMM是抽象的,他是⽤来描述⼀组规则,通过这个规则来控制各个变量的访问⽅式,围绕原⼦性、有序性、可⻅性等展开的。⽽Java运⾏时内存的划分是具体的,是JVM运⾏Java程序时,必要的内存划分。

联系:都存在私有数据区域和共享数据区域。⼀般来说,JMM中的主内存属于共享数据区域,他是包含了堆和⽅法区;同样,JMM中的本地内存属于私有数据区域,包含了程序计数器、本地⽅法栈、虚拟机栈。

实际上,他们表达的是同⼀种含义文章来源地址https://www.toymoban.com/news/detail-419542.html

到了这里,关于为什么会有JMM?从0到1一次性说清楚的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 为什么会有刷掉第一名、刷掉400+的院校?

    本期为大家整理热门院校-“南昌大学”的择校分析,这个择校分析专题会为大家结合:初试复试占比、复试录取规则(是否公平)、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源于研招网,如有错误,欢迎指正,谢谢!

    2024年02月08日
    浏览(60)
  • NFT 为什么会有差异,探索底层的铸造协议

    NFT 的流行,让许多人都对它已经不怎么陌生了。但你真正了解过它么?从表面来看,每个 NFT 之间的性质、特点以及属性和功能等都没有多大的差别,当我们深入了解时才会发现,在不同应用领域的 NFT 之间,也有一些细微的不同。是什么导致了这些差异的存在呢?这个问题

    2024年02月15日
    浏览(44)
  • 【C++入门】你知道C++为什么会有内联函数吗?

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。 我

    2024年02月03日
    浏览(76)
  • 为什么会有分布式锁?分布式锁实现方案

    分布式锁是控制分布式系统之间同步访问共享资源的一种方式。分布式环境下会出现资源竞争的地方都需要分布式锁的协调。 分布式锁的作用:在整个系统提供一个全局、唯一的锁,在分布式系统中每个系统在进行相关操作的时候需要获取到该锁,才能执行相应操作。 服务

    2024年02月08日
    浏览(50)
  • python 一次性删除列表(list)的空白元素(空内容) 或者 一次性删除列表(list)中的指定元素

    看看下述代码: 输出: 当你遇见这种情况,有哪些方法来去除里面的空内容呢(即 \\\'\\\' )? 1.1 删除空内容(方法一) : 输出: 1.2 删除空内容(方法二) : 需要 配合 lambda 表达式 一起使用! 输出: 2.3 删除指定内容 : 输出: 注 :此方法既可以删除空元素,也可以删除指

    2024年02月03日
    浏览(94)
  • 【人工智能】为什么说大模型会有「幻觉」问题,又如何去解决呢

    大家好,我是全栈小5,欢迎阅读文章! 此篇是【话题达人】序列文章,这一次的话题是《如何解决大模型的幻觉问题》 先来了解基本术语和缩写全称,比如LLM。 LLM是Large Language Model的缩写,指的是一种 大规模语言模型 ,可以用来为许多自然语言处理(Natural Language Processing

    2024年02月03日
    浏览(53)
  • 《一次性分割一切》阅读笔记

    目录 0 体验 1 摘要 2 十个问题 参考文献 体验地址 :SEEM - a Hugging Face Space by xdecoder 体验结果 : 将哈士奇和汽车人从图片中分割出来。 尽管对于交互式人工智能系统的需求不断增长,但在视觉理解(例如分割)中的人工智能交互方面,很少有全面的研究。本文受到基于提示的

    2024年02月01日
    浏览(89)
  • 公众号一次性订阅消息

    洛塔服务号回复007获取代码。 之前发布通知,要用订阅通知替代一次性订阅消息,不知道是被骂的太惨还是技术原因,一次性订阅消息还是一直能用。 和模板消息不同的是,一次性订阅消息无需用户关注公众号,但是必须用户点击同意发送才能接收消息。 模板消息:需要关

    2024年02月09日
    浏览(75)
  • 一次性打包学透 Spring

    不知从何时开始,Spring 这个词开始频繁地出现在 Java 服务端开发者的日常工作中,很多 Java 开发者从工作的第一天开始就在使用 Spring Framework,甚至有人调侃“不会 Spring 都不好意思自称是个 Java 开发者”。 之所以出现这种局面,源于 Spring 是一个极为优秀的一站式集成框架

    2023年04月19日
    浏览(64)
  • Python:一次性输出多个量

    有的时候我们在输入一个字符串时,需要在中间加一个int类型变量时,如果一段一段输出就要写三个print,非常麻烦。今天bug君就给大家讲讲如何在Python里一次性输出多个量。 粽所粥汁,在Python里输出需要写 print(\\\"输出内容\\\") ,而输出一个变量则需要写 print(变量名) 。 注意:

    2024年02月04日
    浏览(122)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包