JMM介绍
1.什么是JMM?
2.JMM的三大特性:
1.原子性
2.可见性
3.有序性
3.关于同步的规定:
4.解释说明
JMM中的八种操作:
1.什么是JMM?
​ JMM 是Java内存模型( Java Memory Model),简称JMM。它本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范,是和多线程相关的一组规范。通过这组规范,定义了程序中对各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。需要每个JVM 的实现都要遵守这样的规范,有了JMM规范的保障,并发程序运行在不同的虚拟机上时,得到的程序结果才是安全可靠可信赖的。如果没有JMM 内存模型来规范,就可能会出现,经过不同 JVM 翻译之后,运行的结果不相同也不正确的情况。

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

JMM 抽象出主存储器(Main Memory)和工作存储器(Working Memory)两种。
·主存储器是实例对象所在的区域,所有的实例都存在于主存储器内。比如,实例所拥有的字段即位于主存储器内,主存储器是所有的线程所共享的。
·工作存储器是线程所拥有的作业区,每个线程都有其专用的工作存储器。工作存储器存有主存储器中必要部分的拷贝,称之为工作拷贝(Working Copy)。
所以,线程无法直接对主内存进行操作,此外,线程A想要和线程B通信,只能通过主存进行。

2.JMM的三大特性:
JMM的三大特性:原子性、可见性、有序性。

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

2.可见性
只要有一个线程对共享变量的值做了修改,其他线程都将马上收到通知,立即获得最新值。

3.有序性
​ 有序性可以总结为:在本线程内观察,所有的操作都是有序的;而在一个线程内观察另一个线程,所有操作都是无序的。前半句指 as-if-serial 语义:线程内似表现为串行,后半句是指:“指令重排序现象”和“工作内存与主内存同步延迟现象”。处理器为了提高程序的运行效率,提高并行效率,可能会对代码进行优化。编译器认为,重排序后的代码执行效率更优。这样一来,代码的执行顺序就未必是编写代码时候的顺序了,在多线程的情况下就可能会出错。

​ 在代码顺序结构中,我们可以直观的指定代码的执行顺序, 即从上到下按序执行。但编译器和CPU处理器会根据自己的决策,对代码的执行顺序进行重新排序,优化指令的执行顺序,提升程序的性能和执行速度,使语句执行顺序发生改变,出现重排序,但最终结果看起来没什么变化(在单线程情况下)。

​ 有序性问题 指的是在多线程的环境下,由于执行语句重排序后,重排序的这一部分没有一起执行完,就切换到了其它线程,导致计算结果与预期不符的问题。这就是编译器的编译优化给并发编程带来的程序有序性问题。

Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重排序”的语义,synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行进入。

3.关于同步的规定:
1.线程解锁前,必须把共享变量的值刷新回主内存。

2.线程加锁前,必须将主内存的最新值读取到自己的工作内存。

3.加锁解锁是同一把锁。

4.解释说明
​ 在JVM中,栈负责运行(主要是方法),堆负责存储(比如new的对象)。由于JVM运行程序的实体是线程,而每个线程在创建时,JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域。而JAVA内存模型中规定,所有变量都存储在主内存中,主内存是共享内存区域,所有线程都可以访问。

​ 但线程对变量的操作(读取赋值等)必须在自己的工作内存中进行。首先要将变量从主内存拷贝到自己的工作内存空间,然后对变量进行操作,操作完成后,再将变量写回到主内存。由于不能直接操作主内存中的变量,各个线程的工作内存中存储着主内存中的变量副本,因此,不同的线程之间无法直接访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成。

JMM中的八种操作:
为了支持 JMM,Java 定义了8种原子操作,用来控制主存与工作内存之间的交互:

·read 读取:作用于主内存,将共享变量从主内存传送到线程的工作内存中。
·load 载入:作用于工作内存,把 read 读取的值放到工作内存中的副本变量中。
·store 存储:作用于工作内存,把工作内存中的变量传送到主内存中。
·write 写入:作用于主内存,把从工作内存中 store 传送过来的值写到主内存的变量中。
·use 使用:作用于工作内存,把工作内存的值传递给执行引擎,当虚拟机遇到一个需要使用这个变量的指令时,就会执行这个动作。
·assign 赋值:作用于工作内存,把执行引擎获取到的值赋值给工作内存中的变量,当虚拟机栈遇到给变量赋值的指令时,就执行此操作。
·lock锁定: 作用于主内存,把变量标记为线程独占状态。
·unlock解锁: 作用于主内存,它将释放独占状态。
————————————————
版权声明:本文为CSDN博主「加油进大厂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LYQ20010417/article/details/124138635

JMM(Java内存模型)笔记的更多相关文章

  1. Java多线程专题2: JMM(Java内存模型)

    合集目录 Java多线程专题2: JMM(Java内存模型) Java中Synchronized关键字的内存语义是什么? If two or more threads share an object, ...

  2. Java 线程 — JMM Java内存模型

    JMM Java Memory Model,Java内存模型,属于语言级的内存模型 并发编程中存在的问题: 如何通信:用于线程之间交换信息.两种方式:共享内存,消息传递 如何同步:用于控制不同线程间操 ...

  3. Java并发编程:JMM(Java内存模型)和volatile

    1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...

  4. Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解

    目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...

  5. JMM——Java内存模型抽象|八种同步操作|操作规则

    JMM 调用栈&本地变量在线程栈上 对象整体在堆上(包括其本地变量,不论类型),栈有其引用即可访问, 线程调用同一个对象时,是访问该对象的私有拷贝 每个CPU有自己的高速缓存 高速缓存存在意义 ...

  6. JMM - Java内存模型

    内存模型的作用是定义变量的访问规则.包含:实例字段.静态字段.构成数组对象的元素.不包括局部变量和方法参数等线程私有变量. JMM所有变量都在主存,每个线程都有自己的工作内存.线程的工作内存中保存了线 ...

  7. 多线程并发之java内存模型JMM

    多线程概念的引入是人类又一次有效压寨计算机的体现,而且这也是非常有必要的,因为一般运算过程中涉及到数据的读取,例如从磁盘.其他系统.数据库等,CPU的运算速度与数据读取速度有一个严重的不平衡,期间如果 ...

  8. 多线程系列八:线程安全、Java内存模型(JMM)、底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  9. 对多线程java内存模型JMM

    多线程概念的引入体现了人类重新有效压力寨计算机.这是非常有必要的,由于所涉及的读数据的过程中的一般操作,如从磁盘.其他系统.数据库等,CPU计算速度和数据读取速度已经严重失衡.假设印刷过程中一个线程将 ...

  10. Java内存模型学习笔记(一)—— 基础

    1.并发编程模型的分类 在并发编程中,我们需要处理两个关键的问题:1.线程间如何通信,2.线程间如何同步.通信是指线程之间以何种机制来交换信息,同步是指程序用于不同线程之间操作发生相对顺序的机制. 在 ...

随机推荐

  1. JDK的版本有多少种,Java开发者应该选择哪一种?

    JDK的版本有多少种,Java开发者应该选择哪一种?先说结果,一般情况下,我们多数会选择OpenJDK或者AdoptOpenJDK的JDK实现,因为这是最精简最标准的版本,而且没有商业风险.另外,需要 ...

  2. 监控平台prometheus+grafana+snmp_explorer+blackbox_exporter+alertmanager

    一.背景介绍 公司需要监控交换机和IP设备,能够放在展示屏幕,及时发出告警信息.网上有很多监控软件,prometheus系列已经能够满足我们需求.prometheus功能强大,本次只用到一部功能.咱们 ...

  3. python 链接云端数据库/远程数据库 可以使用原始Odbc

    class MySqlOdbc: def __init__(self): self.sqlhead = None # 当前数据链接句柄 self.mycursor = None # 当前游标 &quo ...

  4. 使用elemeng-plus控制台报错:$weight

    使用element-plus最开始按需使用,加入的组件少没有问题,但组件引入多了以后发现控制台会报下面的警告: Deprecation Warning: $weight: Passing a numb ...

  5. pycharm 连接服务器进行操作比 Xshell 更简单!

    一.SSH 连接 pycharm 中通过 SSH 连接服务器非常的简单,只需要简单的几步操作就能完成,如下图 1.第一步:点击开启 SSH 会话 2.第二步:填入对应的连接信息,点击 OK 3.这个时 ...

  6. 腾讯云静态资源放到cos存储桶里,并开启CDN自定义域名加速

    首先根据腾讯云cos对应文档创建cos存储桶(权限为共有读私有写),上传build之后的静态文件到存储桶根目录,然后配置静态网站,然后访问静态网站的访问节点,如果报错请配置索引文档和错误文档为inde ...

  7. HJ92 在字符串中找出连续最长的数字串

    描述 输入一个字符串,返回其最长的数字子串,以及其长度.若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置) 本题含有多组样例输入. 输入描述: 输入一个字符串. 输出描述: 输出字符串中 ...

  8. Unity中UGUI图片跟随文本自适应方法

    字体和图片层级如下 Text添加Content Size Fitter Image设置锚点

  9. 【当年笔记】集合之Map

    Map 常用的实现类如下: Hashtable :Java 早期hash类,线程安全,不支持 null 键和值,因为它的性能不如 ConcurrentHashMap,所以基本不用. HashMap : ...

  10. 基于winds10 安装docker 踩坑记录

    1.官方下载 https://www.docker.com/ 2.根据提示安装 并重庆计算机3.双击运行 报 Docker Desktop is shutting down 提示  计算机c: 盘 A ...