提升--21---JMM(Java内存模型)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • JMM--Java Memory Model
    • JMM 定义
    • JMM规则:
    • 线程间通信的步骤:
  • JMM的三大特性:
    • 原子性(Atomicity)
    • 可见性:
    • 有序性:
  • JMM中的八种内存操作:


JMM–Java Memory Model

JMM 定义

JMM 是Java内存模型(Java Memory Model),简称JMM。它本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范,

  • 内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节
  • JMM 和 JVM的内存结构,不是一个东西!!!!

JMM规则:

  1. JMM规定了所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory)

  2. 线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。

  3. 不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。
    在这里插入图片描述

image.png
全局描述。 在处理指令时,CPU会拉取数据,优先级是从L1到L2到L3,如果都没有,需要去主内存中拉取,JMM就是在CPU和主内存之间,来协调,保证可见、有序性等操作

  • CPU核心,就是CPU核心(寄存器)
    缓存是CPU的缓存,CPU的缓存分为L1(线程独享),L2(内核独享),L3(多核共享)
  • JMM就是Java内存模型的核心,可见性,有序性都基于这实现。
  • 主内存JVM,就是你堆内存。

线程间通信的步骤:

首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
然后,线程B到主内存中去读取线程A之前已更新过的共享变量。
在这里插入图片描述

本地内存A和B有主内存中共享变量x的副本。假设初始时,这三个内存中的x值都为0。

  1. 线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。
  2. 当线程A和线程B需要通信时(如何激发?–隐式),线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。
  3. 随后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。

从整体来看,这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。

JMM的三大特性:

Java内存模型是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的,那我们依次看一下这三个特征:

原子性(Atomicity)

一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。

基本类型数据的访问大都是原子操作,long 和double类型的变量是64位,但是在32位JVM中,32位的JVM会将64位数据的读写操作分为2次32位的读写操作来进行,这就导致了long、double类型的变量在32位虚拟机中是非原子操作,数据有可能会被破坏,也就意味着多个线程在并发访问的时候是线程非安全的。

可见性:

一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量的这种修改(变化)。

Java内存模型是通过将在工作内存中的变量修改后的值同步到主内存,在读取变量前从主内存刷新最新值到工作内存中,这种依赖主内存的方式来实现可见性的。

在这里插入图片描述

有序性:

在这里插入图片描述

JMM中的八种内存操作:

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

  • read 读取:作用于主内存,将共享变量从主内存传送到线程的工作内存中。

  • load 载入:作用于工作内存,把 read 读取的值放到工作内存中的副本变量中。

  • store 存储:作用于工作内存,把工作内存中的变量传送到主内存中。

  • write 写入:作用于主内存,把从工作内存中 store 传送过来的值写到主内存的变量中。

  • use 使用:作用于工作内存,把工作内存的值传递给执行引擎,当虚拟机遇到一个需要使用这个变量的指令时,就会执行这个动作。

  • assign 赋值:作用于工作内存,把执行引擎获取到的值赋值给工作内存中的变量,当虚拟机栈遇到给变量赋值的指令时,就执行此操作。

  • lock锁定: 作用于主内存,把变量标记为线程独占状态。

  • unlock解锁: 作用于主内存,它将释放独占状态。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软 Power Platform 零基础 Power Pages 网页搭建实际案例实践(三)

微软 Power Platform 零基础 Power Pages 网页搭建教程之案例实践学习(三)结合Power Apps和Power Automate Power Pages 实际案例学习 微软 Power Platform 零基础 Power Pages 网页搭建教程之案例实践学习(三)结合Power Apps和Po…

练习十一:简单卷积器的设计

简单卷积器的设计 1,任务目的:2,明确设计任务2.1,目前这部分代码两个文件没找到,见第5、6节,待解决中。 ,卷积器的设计,RTL:con1.v4,前仿真和后仿真,测试信号…

Python入门07循环及常见的数据结构

目录 1 循环的语法结构2 break和continue的示例3 可迭代对象4 列表5 元组6 列表和元组的应用场景7 集合8 字典9 生成器 1 循环的语法结构 在Python中,循环是一种控制结构,用于重复执行一段代码,直到满足特定条件。Python中有两种循环结构&am…

flink sink多个topic

flink stream数据 动态写入多个topic flink1.15之前 import org.apache.flink.streaming.api.scala._ import org.apache.flink.streaming.connectors.kafka.{FlinkKafkaProducer, KafkaSerializationSchema} import org.apache.kafka.clients.producer.ProducerRecordobject…

Spring切面编程

切面编程 代码地址: orbit-hub/spring-boot-samples at master (github.com)https://github.com/orbit-hub/spring-boot-samples/tree/master 切面执行顺序 Spring5以后顺序就一切正常 正常:前置通知目标方法返回通知后置通知 异常: 前置通知目标方…

C++12.4

沙发床的多继承 多继承代码实现沙发床沙发床继承于沙发和床 代码&#xff1a; #include <iostream>using namespace std;//封装 沙发 类 class Sofa { private:string sitting;double *size; public://无参构造函数Sofa() {cout << "Sofa::无参构造函数&quo…

京东运营数据分析(京东数据采集):2023年10月京东护肤行业品牌销售排行榜

鲸参谋监测的京东平台10月份护肤市场销售数据已出炉&#xff01; 鲸参谋数据显示&#xff0c;2023年10月份&#xff0c;京东平台上护肤市场的销量为2000万&#xff0c;环比增长约28%&#xff0c;同比降低约26%&#xff1b;销售额为25亿&#xff0c;环比增长约24%&#xff0c;同…

Java基本数据类型、包装类及拆装箱详解

Java的基本数据类型和对应的包装类是Java语言中处理数据的两个关键概念。基本数据类型提供了简单而高效的方式来存储数据&#xff0c;而包装类使得基本数据类型具有对象的特性。本文将深入探讨基本数据类型与包装类的应用场景及详细描述&#xff0c;并对自动拆箱和装箱的源码实…

了解完Devops,让我们再来看看什么是SRE吧!

SRE SRE 全称是 Site Reliability Engineering&#xff0c;即网站稳定性工程师。最早是由 Google 提出&#xff0c;并且在其工程实践中发扬光大。这个团队设立目的是帮助 Google 生产环境服务运行更稳定、健壮、可靠。不同于中小型规模公司&#xff0c;Google服务于十几亿用户…

SpringBoot+SSM项目实战 苍穹外卖(3)

继续上一节的内容&#xff0c;本节完成菜品管理功能&#xff0c;包括公共字段自动填充、新增菜品、菜品分页查询、删除菜品、修改菜品。 目录 公共字段自动填充新增菜品文件上传实现新增菜品实现 useGeneratedKeys 菜品分页查询删除菜品修改菜品根据id查询菜品实现修改菜品实现…

geemap学习笔记015:下载哨兵2号(Sentinel-2)数据

前言 使用GEE下载数据应该是最常见的功能了&#xff0c;今天就介绍一下如何使用geemap下载哨兵2号(Sentinel-2)数据&#xff0c;分别包括自己画感兴趣&#xff0c;以及利用Assets中的shp文件进行下载。 1 自己画感兴趣下载哨兵2号影像 import geemap import eeMap geemap.M…

金蝶云星空表单插件单据体批量删除,序号自增

文章目录 金蝶云星空表单插件单据体批量删除&#xff0c;序号自增字段标识说明表单插件获取单据体数据包移除物料为空的行其他移除物料为空的行的方式&#xff0c;但是测试不通过&#xff0c;不建议使用序号重新生成测试 金蝶云星空表单插件单据体批量删除&#xff0c;序号自增…

Apache Doris 详细教程(三)

7、监控和报警 Doris 可以使用 Prometheus 和 Grafana 进行监控和采集&#xff0c;官网下载最新版即可。 Prometheus 官网下载&#xff1a;https://prometheus.io/download/ Grafana 官网下载&#xff1a;https://grafana.com/grafana/download Doris 的监控数据通过 FE 和…

【矩阵论】Chapter 3—线性映射和线性变换知识点总结复习

文章目录 1 线性映射及其矩阵表示2 线性映射的值域&#xff08;像&#xff09;和核3 线性变换4 酉变换和正交变换5 同态和同构6 不变子空间 1 线性映射及其矩阵表示 映射定义 设 A , B A,B A,B是两个集合&#xff0c;如果存在一个规则 f f f&#xff0c;使得对于 A A A中的元素…

B2B公司如何寻找意向客户的联系方式?

在B2B公司的营销过程中&#xff0c;少不了寻找意向客户的阶段&#xff0c;这也是销售过程中非常重要的一步。 很多新人都是拿到客户联系方式&#xff0c;就直接打电话拜访&#xff0c;俗话说不打没有准备的仗&#xff0c;因此在拜访客户之前就应该做好功课&#xff0c;充分了解…

数据结构和算法专题---2、算法思想

上文讲到算法的概念、复杂度&#xff0c;本文给大家介绍具体的算法思想&#xff0c;让大家对算法设计理念有个认识&#xff0c;后续再分别介绍各种算法。 算法思想 算法是解决问题的一种思想和方法&#xff0c;其基本思想是将一个复杂问题分解为多个简单的子问题&#xff0c;…

全网最新最全的自动化测试教程:python+pytest接口自动化-请求参数格式的确定

我们在做接口测试之前&#xff0c;先需要根据接口文档或抓包接口数据&#xff0c;搞清楚被测接口的详细内容&#xff0c;其中就包含请求参数的编码格式&#xff0c;从而使用对应的参数格式发送请求。例如某个接口规定的请求主体的编码方式为 application/json&#xff0c;那么在…

跟我学c++高级篇——动态反射之二动态列表

一、动态生成列表 在上一篇中实现了一个Map映射&#xff0c;其实就是一个表。但那个表有点维护和扩展上的不方便&#xff0c;所以后为又开始用静态展开递归的方式来遍历枚举。其不管是怎么做&#xff0c;都是要得到整个枚举体的信息&#xff0c;然后才能进行处理。 这次使用一…

医院信息化专业人员必备医院业务运作及管理流程知识(详细)

业务流程是一家医院运作的基础,医院所有业务都需要流程加以驱动。熟知医院各项业务,了解医院管理流程,有利于医院工作人员更好地投入自身岗位,提高工作效率。本文整理了常见医院业务运作及管理流程,仅供参考! 【门诊业务】 一、门诊业务的特点: 1.接诊病人多,就诊时…

clang的AST源码分析

clang的AST源码分析 QualType类 重点关注函数&#xff1a; /// Return true if this QualType doesnt point to a type yet.bool isNull() const {return Value.getPointer().isNull();}被RecursiveASTVisitor调用 template <typename Derived> bool RecursiveASTVisi…