Java内存模型(JMM)详解

文章目录

  • 1、Java内存模型
  • 2、JMM的核心概念
    • 1)主内存与工作内存
    • 2)内存可见性
    • 3)JMM的三大特性:原子性、可见性、有序性。
  • 3、JMM中的八种操作
  • 4、Happens-before 规则
  • 5、样例:

1、Java内存模型

Java内存模型(Java Memory Model,JMM)是一种抽象的概念,用于定义多线程程序如何与内存进行交互。JMM并不真实存在,它是一种规范,规定了程序中变量在内存中的访问方式。

计算机在执行程序时,每条指令都是在CPU中执行的。而执行指令的过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程,跟CPU执行指令的速度比起来要慢的多(硬盘 < 内存 <缓存cache < CPU)。因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时,就可以直接从它的高速缓存中读取数据或向其写入数据了。当运算结束之后,再将高速缓存中的数据刷新到主存当中。
在这里插入图片描述

2、JMM的核心概念

1)主内存与工作内存

  • 主内存:所有变量都存储在主内存中,主内存是共享的。
  • 工作内存:每个线程都有自己的工作内存,工作内存中保存了主内存中变量的副本。线程对变量的所有操作(读取、写入)都在工作内存中进行,最后再将结果同步回主内存。

2)内存可见性

  • JMM规定了线程对变量的读取和写入顺序,确保变量的修改在其他线程中可见。即,当一个线程修改了变量的值,其他线程最终能看到这个修改后的值。

3)JMM的三大特性:原子性、可见性、有序性。

  • 原子性
    一个或多个操作,要么全部执行,要么全部不执行(执行的过程中是不会被任何因素打断的)。

  • 可见性
    一个线程对共享变量的修改,能够被其他线程看到。通过 volatile 关键字、锁(如 synchronized)来实现可见性。

  • 程序的执行在实际运行时可能会被重排序,但JMM提供了一定的保证,使得某些操作在多线程环境中会按照程序的顺序执行。

3、JMM中的八种操作

JMM抽象了线程和主内存之间的关系,定义了以下八种操作来完成主内存和工作内存之间的交互:

• lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。

• unlock(解锁):作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。

• read(读取):作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用。

• load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。

• use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。

• assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。

• store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。

• write(写入):作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中。

在这里插入图片描述

4、Happens-before 规则

JMM还定义了一个重要的概念:happens-before,它是判断数据是否存在竞争、线程是否安全的依据。happens-before原则规定了以下几种情况:

• 程序次序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。

• 监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。

• volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。

• 传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。

• start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。

• join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。

• 中断规则:对线程interrupt()方法的调用happens-before于被中断线程的代码检测到中断事件的发生。

• 终结器规则:对象的构造函数执行、结束happens-before于它的finalize()方法的开始。

JMM定义了一组 happens-before 规则,用来确定操作之间的顺序,确保内存可见性和有序性

5、样例:

public class VolatileExample {
    private volatile boolean flag = false;

    public void writer() {
        flag = true;  // 写操作,保证对其他线程可见
    }

    public void reader() {
        if (flag) {  // 读操作,确保读取到最新值
            System.out.println("Flag is true");
        }
    }
}

public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;  // synchronized 确保可见性和原子性
    }

    public synchronized int getCount() {
        return count;  // synchronized 确保读取最新值
    }
}

在 VolatileExample 中,flag 变量使用 volatile 修饰,确保在一个线程修改 flag 后,其他线程能够立即看到变化。在 SynchronizedExample 中,increment 和 getCount 方法使用 synchronized 修饰,确保操作的可见性和原子性。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/719253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis常见数据类型及其常用命令详解

文章目录 一、Redis概述二、Redis常用命令1.通用命令1.1 KEYS&#xff1a;查看符合模板的所有 key1.2 DEL&#xff1a;删除一个指定的 key1.3 EXISTS&#xff1a;判断 key 是否存在1.4 EXPIRE&#xff1a;给一个 key 设置有效期&#xff0c;有效期到期时该 key 会被自动删除1.5…

gridview自带编辑功能如何判断用户修改的值的合法性

在使用GridView的编辑功能更新值时&#xff0c;确保输入的值合法性是十分重要的。为了实现这一点&#xff0c;你可以在GridView的RowUpdating事件中加入代码来检查用户输入的值。如果发现输入的值不合法&#xff0c;你可以取消更新操作并向用户显示错误消息。下面是如何实现的步…

区区微服务,何足挂齿?

背景 睿哥前天吩咐我去了解一下微服务&#xff0c;我本来想周末看的&#xff0c;结果周末没带电脑&#xff0c;所以只能周一看了。刚刚我就去慕课网看了相关的视频&#xff0c;然后写一篇文章总结一下。这篇文章算是基础理论版&#xff0c;等我之后进行更多的实践&#xff0c;…

Matlab初识:什么是Matlab?它的历史、发展和应用领域

目录 一、什么是Matlab&#xff1f; 二、Matlab的历史与发展 三、Matlab的应用领域 四、安装和启动Matlab 五、界面介绍 六、第一个Matlab程序 七、总结 一、什么是Matlab&#xff1f; Matlab 是由 MathWorks 公司开发的一款用于数值计算、可视化以及编程的高级技术计算…

vue中axios从content-disposition响应头获取中文名

在Vue中使用axios请求文件时&#xff0c;服务器可能会返回带有Content-Disposition响应头的文件&#xff0c;其中可能包含文件名的编码信息。如果你需要解码这个文件名&#xff0c;可以使用JavaScript的内置URL API来处理。 Java中用于设置HTTP响应头的&#xff0c;通常在Web开…

HTML5新标签

HTML5 特点 新标签 <header>...<header> 头部标签 <footer>...<footer> 尾部标签 <section>...<section> 内容区块 <article>...&#xff0c;article> 表示页面中的独立内容 <aside>...<aside> 标签定义其所处…

JavaScript Window对象之(BOM、JS 执行机制、location对象、navigator对象、histroy对象、本地存储)

目录 1. BOM(浏览器对象模型)2. JS 执行机制3. location对象4. navigator对象5. histroy对象6. 本地存储6.1 localStorage6.2 sessionStorage 1. BOM(浏览器对象模型) BOM(Browser Object Model)是浏览器对象模型。其中window对象是JavaScript中一个全局的顶级对象基本的BOM属性…

定个小目标之刷LeetCode热题(23)

今天写这道题&#xff0c;背过八股文的都应该知道LRU算法缓存的基本原理&#xff0c;在 Java 语言中&#xff0c;同样有类似的数据结构 LinkedHashMap&#xff0c;本题我们采用自己创建哈希表双链表的形式简单实现一下 对于get操作&#xff1a;通过cache.get(key)获取&#xff…

【经典爬虫案例】用Python爬取微博热搜榜!

一、爬取目标 本次爬取的是: 微博热搜榜 &#xff08;代码也可直接在下方拿&#xff09;&#xff1a; ​ 分别爬取每条热搜的&#xff1a; 热搜标题、热搜排名、热搜类别、热度、链接地址。 下面&#xff0c;对页面进行分析。 经过分析&#xff0c;此页面没有XHR链接通过&am…

CSDN 自动上传图片并优化Markdown的图片显示

文章目录 完整代码一、上传资源二、替换 MD 中的引用文件为在线链接参考 完整代码 完整代码由两个文件组成&#xff0c;upload.py 和 main.py&#xff0c;放在同一目录下运行 main.py 就好&#xff01; # upload.py import requests class UploadPic: def __init__(self, c…

VBA学习(6): 调整工作表中所有图表尺寸并使其大小相同

有时候&#xff0c;我们想要将工作表中的所有图表进行缩放操作&#xff0c;且要求这些图表调整后的尺寸大小相同。如果使用手动拖放调整&#xff0c;看似大小相同&#xff0c;实际可能有差异。当然&#xff0c;也可以选取所有的图表后&#xff0c;在工作表选项卡中输入其宽度和…

TOP10!YashanDB斩获广东省优秀信创产品与解决方案双料荣誉

近日&#xff0c;2024广东软件风云榜结果出炉&#xff0c;表彰为广东软件产业和数字经济、新型工业化发展作出突出贡献的企业、企业家、优秀产品等。深算院崖山数据库系统 YashanDB荣获广东省“2024年优秀信息技术应用创新产品TOP10”和“2024年优秀信息技术应用创新行业应用解…

LeetCode 1789, 6, 138

目录 1789. 员工的直属部门题目链接表要求知识点思路代码 6. Z 字形变换题目链接标签思路代码 138. 随机链表的复制题目链接标签思路代码 1789. 员工的直属部门 题目链接 1789. 员工的直属部门 表 表Employee的字段为employee_id&#xff0c;department_id和primary_flag。…

SpringBoot购物网站

摘要 随着信息技术的高速发展&#xff0c;二十一世纪的网络技术和网络应用正在快速融入人们的生活&#xff0c;并且由于网络服务以及网络应用日渐普及&#xff0c;人们对于现在生活的需求也随之增长&#xff0c;而网上购物的便捷对人们的吸引力越来越大&#xff0c;购物网站可…

Android 大话binder通信 (上)

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章 本文摘要 用故事的方式把binder通信的整个过程都描述出来&#xff0c;binder通信都经历了哪些节点&#xff0c;在这些节点上的数据有哪些变化&#xff0c;同时还对binder通…

触控MCU芯片(1):英飞凌PSoC第6代第7代

前言: 说到触摸MCU芯片,这个历史也是很久了,比如日常经常接触到的洗衣机、电冰箱、小家电,隔着一层玻璃,轻轻一按就能识别按键,感觉比过去纯机械式的按键更高级更美观,不仅白电,现在很多汽车也都在进行触摸按键的改版,不再使用笨重的机械按键,比如空调调温按键、档位…

淘宝评论电商API接口,揭示用户真实评价

随着互联网的快速发展&#xff0c;电子商务已经成为了人们生活中不可或缺的一部分。淘宝作为中国最大的在线购物平台&#xff0c;拥有数以亿计的消费者和商家。而用户评价作为消费者了解商品和服务的重要途径&#xff0c;对于商家的信誉和销售有着至关重要的影响。因此&#xf…

SCADA软件地毯式介绍,你想知道的都在这里.

很多小伙伴对SCADA很陌生&#xff0c;殊不知这个可是智慧工业制造的大脑和中枢神经&#xff0c;很多指令的发出&#xff0c;监控状态的现实都得通过这个系统&#xff0c;本文详解介绍一下什么是SCADA&#xff0c;重大作用&#xff0c;其在工业制造中的位置&#xff0c;以及市面…

Export S parameter sweep data 导出 S 参数扫描代码

Export S parameter sweep data 导出 S 参数扫描代码 正文正文 相信有不少小伙伴们会比较苦恼一件事情,就是 Lumerical Script 中的绘图并不智能。功能较为简陋以至于图像展现时不够美观,因此,很多时候我们需要将仿真数据导出使用。那么如何导出仿真数据呢?在 Lumerical S…

【Linux进程通信】Linux进程间的无声对话:匿名管道与命名管道技术

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a;我们已经知道了进程和文件的基本理论&#xff0c;知道了进程和文件的重要性。进程具有独立性&#xff0c;所以两个进程不能直接通信&#xff0c;那么进程间应该怎样通信呢&#xff1f;我们今天来解开其…