java八股文面试[多线程]——主内存和工作内存的关系

news2025/1/17 1:02:42

JAVA内存模型(JMM)
共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。
上面的工作内存其实是java内存模型抽象出来的概念,下面简要介绍一下java内存模型(JMM)。
java内存模型(java memory model): 描述了java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节。

不同的平台,内存模型是不一样的,我们可以把内存模型理解为在特定操作协议下,对特定的内存高速缓存进行读写访问的过程抽象。Java 虚拟机规范中试图定义一种 Java 内存模型(Java Memory Model,简称 JMM)屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果,不必因为不同平台上的物理机的内存模型的差异,对各平台定制化开发程序。
更具体一点说,Java 内存模型提出目标在于,定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

在这里插入图片描述

 

从上图可以得出结论:

  • 所有的变量都存储在主内存
  • 每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存该变量的一份拷贝)。

JMM关于synchronized的两条规定:

  1. 线程解锁前,必须把共享变量的最新值刷新到主内存中
  2. 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值。(加锁和解锁需要是同一把锁)

线程解锁前对共享变量的修改在下次加锁前对其他线程可见。

JVM主内存与工作内存描述

JVM将内存为主内存工作内存两个部分。

主内存: 主要包括本地方法区和 

  • Java 内存模型规定了所有变量都存储在主内存(Main Memory)中(此处的主内存与介绍物理硬件的主内存名字一样,两者可以互相类比,但此处仅是虚拟机内存的一部分)。

工作内存: 每个线程都有一个工作内存,工作内存中主要包括两个部分,一个是属于该线程私有的和 对主存部分变量拷贝的寄存器(包括程序计数器PC和cup工作的高速缓存区)。

  • 每个线程都有自己的工作内存(Working Memory,又称本地内存.),线程的工作内存中保存了该线程使用到的变量,该变量是主内存中的共享变量的副本拷贝
  • (工作内存是 JMM 的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。)

在这里插入图片描述

 线程执行的时候,将首先从主内存读值,再load到工作内存中的副本中,然后传给处理器执行,执行完毕后再给工作内存中的副本赋值,随后工作内存再把值传回给主存,主存中的值才更新。
在这个过程中如果出现多个线程同时在处理这些值,岂不是会出现并发问题

在这里插入图片描述

1、所有的变量都存储在主内存中(虚拟机内存的一部分),对于所有线程都是共享的
2、每个线程都有自己的工作内存,工作内存中保存的是主存中某些变量的值的副本拷贝,线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存中的变量。
3、线程之间无法直接访问对方的工作内存中的变量值的,线程间变量的传递均需要通过主内存来完成。
这种划分与Java运行时内存区域中堆、栈、元空间等的划分是不同层次的划分,两者基本没有关系。硬要联系的话,大致上主内存对应Java堆中对象的实例数据部分、工作内存对应栈的部分区域;从更低层次上说,主内存对应物理硬件内存、工作内存对应寄存器和高速缓存

JVM内存间交互规则

关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,Java 内存模型中定义了下面 8 种操作来完成。
在这里插入图片描述

  1. Lock(锁定):作用于主内存中的变量,把一个变量标识为被一个线程独占的状态。
  2. Unlock(解锁):作用于主内存中的变量, 将一个变量从锁定状态(Lock)释放出来,释放后的变量才可以被其他线程锁定(Lock)
  3. Read(读取):作用于主内存中的变量,将一个变量的值从主内存传输到工作内存中,以便随后的load操作使用
  4. Load(加载):作用于工作内存中的变量,把read操作从主内存中得到的变量的值放入工作内存的变量副本中。
  5. Use(使用):作用于工作内存中的变量,把工作内存中一个变量的值传递给执行引擎。(每当虚拟机遇到一个需要使用到变量的值的字节码指令时就会执行这个操作。)
  6. Assign(赋值):作用于工作内存中的变量,把一个从执行引擎接收到的值赋值给工作内存中的变量。(每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。)
  7. Store(存储):作用于工作内存中的变量,把工作内存中的一个变量的值传送到主内存中,以便随后 write 操作使用。
  8. Write(写入):作用于主内存中的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中。

需知:

  • 在将变量从主内存读取到工作内存中,必须顺序执行read(读取)、load(加载)
  • 要将变量从工作内存同步回主内存中,必须顺序执行store(存储)、write(写入)

这8种操作必须遵循以下规则:

  1. 不允许read(读取)和load(加载)、store(存储)和write(写入)操作之一单独出现。即不允许一个变量从主内存被读取了,但是工作内存不接受,或者从工作内存回写了但是主内存不接受。

    不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步会主内存中

  2. 不允许一个线程丢弃它最近的一个assign(赋值)操作,即变量在工作内存被更改后必须同步改更改回主内存。即:执行store(存储),write(写入)操作

  3. 工作内存中的变量在没有执行过assign(赋值)操作时,不允许无意义的同步回主内存。 即:执行store(存储),write(写入)操作

  4. 在执行use(使用)前必须已执行load(加载),在执行store(存储)前必须已执行assign(赋值)

  5. 一个变量在同一时刻只允许一个线程对其执行lock操作,一个线程可以对同一个变量重复执行多次lock,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现。

  6. 一个线程在lock一个变量的时候,将会清空工作内存中的此变量的值,执行引擎在use(使用)前必须重新read(读取)和load(加载)初始化变量的值。

  7. 在执行unlock之前,必须首先执行了store(存储)和write(写入)操作

    对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)

  8. 线程不允许unlock其他线程lock操作。并且unlock操作必须是在本线程的lock操作之后。

    如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。

从上面可以看出,把变量从主内存复制到工作内存需要顺序执行read、load,从工作内存同步回主内存则需要顺序执行store、write。总结:

  • read、load、use必须成对顺序出现,但不要求连续出现。assign、store、write同之;
  • 变量诞生和初始化:变量只能从主内存“诞生”,且须先初始化后才能使用,即在use/store前须先load/assign;
  • lock一个变量后会清空工作内存中该变量的值,使用前须先初始化;unlock前须将变量同步回主内存;
  • 一个变量同一时刻只能被一线程lock,lock几次就须unlock几次;未被lock的变量不允许被执行unlock,一个线程不能去unlock其他线程lock的变量。

JVM先行发生原则

Java内存模型具备一些先天的“有序性”,即不需要通过任何同步手段(volatile、synchronized等)就能够得到保证的有序性,这个通常也称为happens-before原则

 

知识来源:

【23版面试突击】你知道主内存和工作内存的关系?_哔哩哔哩_bilibili

【Java多线程】内存模型JMM—主内存与工作内存分析_主内存和工作内存_Archie_java的博客-CSDN博客

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

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

相关文章

正中优配:股票经手费必须交吗?

在股票出资中,经手费是一个不可避免的要素。那么,股票经手费有必要交吗?从多个视点来看,这个问题需求进行必定的剖析。 法令视点:股票经手费有必要交 从法令视点来看,股票经手费有必要交。依据《证券法》的…

SQL 语句继续学习之记录三

一,数据的插入(insert 语句的使用方法) 使用insert语句可以向表中插入数据(行)。原则上,insert语句每次执行一行数据的插入。 列名和值用逗号隔开,分别扩在()内,这种形式称为清单。…

Llama模型结构解析(源码阅读)

目录 1. LlamaModel整体结构流程图2. LlamaRMSNorm3. LlamaMLP4. LlamaRotaryEmbedding 参考资料: https://zhuanlan.zhihu.com/p/636784644 https://spaces.ac.cn/archives/8265 ——《Transformer升级之路:2、博采众长的旋转式位置编码》 前言&#x…

安科瑞风力发电场集中监控系统解决方案-安科瑞黄安南

作为清洁能源之一,风力发电场近几年装机容量快速增长。8月17日,国家能源局发布1-7月份全国电力工业统计数据。截至7月底,全国累计发电装机容量约27.4亿千瓦,同比增长11.5%。其中,太阳能发电装机容量约4.9亿千瓦&#x…

Oracle数据传输加密方法

服务器端“dbhome_1\NETWORK\ADMIN\”sqlnet.ora文件中添加 SQLNET.ENCRYPTION_SERVER requested SQLNET.ENCRYPTION_TYPES_SERVER (RC4_256) 添加后新的链接即刻生效,服务器无需重新启动。 也可以通过Net manager管理工具添加 各个参数含义如下: 是…

Web开发模式、API接口、restful规范、序列化和反序列化、drf安装和快速使用

一 Web开发模式 1. 前后端混合开发模式 前后端混合开发模式是一种开发方式,将前端和后端的开发工作结合在一起,以加快项目的开发速度和 提高协作效率。这种模式通常用于快速原型开发、小型项目或敏捷开发中。在前后端混合开发模式中,前端和…

【MyBatis】自定义resultMap三种映射关系

目录 一、一对一映射(One-to-One) 1.1 表关系 1.2 resultMap设置自定义映射 二、一对多映射(One-to-Many) 2.1 创建实体 2.2 级联方式处理映射关系 2.3 定义SQL 2.4 OrderMapper接口 2.5 编写业务逻辑层 2.6 Junit测试…

港联证券:游资爆炒中电环保,还有谁在蹭核污染防治概念?

8月28日,核污染防治概念股持续大涨,建工修复(300958.SZ)、捷强配备(300875.SZ)、东方园林(002310.SZ)、华盛昌(002980.SZ)等涨停。 中小市值的概念股成为游资…

人工智能学习专栏

这个专栏就专门用来记录自己的深度学习的历程吧。从做MCU开始、Soc、Linux系统转行到AI领域,其过程是痛苦的。至少数学这块,那是花了很多时间去从头去学。但是还是有很多不懂的地方。坚持!!!!

03 最长连续序列

最长连续序列 题解 哈希(O(n)) 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 题解 哈希(O(n)) class Solution { public:int long…

升级iOS17后iPhone无法连接App Store怎么办?

最近很多用户反馈,升级最新iOS 17系统后打开App Store提示"无法连接",无法正常打开下载APP。 为什么升级后无法连接到App Store?可能是以下问题导致: 1.网络问题导致App Store无法正常打开 2.网络设置问题 3.App Sto…

微信报修系统有什么优势?怎么提升企业维修工作效率与管理水平?

随着智能化时代的到来,企业、事业单位的现代化设备数量和种类不断增加,原本繁琐的报修、填写记录、检修管理等工作得以简化。从发起报修到维修,以及维修之后给予评价的整个过程,通过手机微信报修系统均能看到,既省时又…

算法---二叉树中的最大路径和

题目 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root &…

IC698CRE040 GE 实现跨多个UPS设备的随处可见性

IC698CRE040 GE 实现跨多个UPS设备的随处可见性 通过人工智能、digital twin技术、由高级分析支持的人类洞察力以及独立于供应商的工业软件,效率和敏捷性正在发生巨大变化。施耐德电气通过为未来打造的弹性和可持续解决方案实现下一代工业自动化。 EcoStruxure自…

出现ZooKeeper JMX enabled by default这种错误的解决方法

系列文章专栏 学习以来遇到的bug/问题专栏 文章目录 系列文章专栏 前言 一 问题描述 二 解决方法 2.1 可能的原因分析 2.2 小编的问题解决方法 First:检查/etc/profile里面zookeeper的环境变量配置 Second:检查 zookeeper/conf/zoo.cfg里面的d…

拆解即时通讯行销,如何提升讯息开启率达300%?

图片来源:SaleSmartly官网 科技日新月异,今时今日商家均转战网络世界,开设网店售卖产品或服务,不少人都会转用即时通讯(Instant Messaging,简称IM)软件来和客户联络和宣传,因为即时通…

Unity3D 如何在ECS架构下,用Unity引擎进行游戏开发详解

前言 Unity3D是一款强大的游戏引擎,它提供了丰富的功能和工具,可以帮助开发者快速构建高质量的游戏。而Entity Component System(ECS)是Unity3D中一种新的架构模式,它可以提高游戏的性能和可扩展性。本文将详细介绍在…

自动化运维:Ansible脚本之playbook剧本

目录 一、理论 1.playbooks 2.YAML 3.使用ansible批量安装apache服务 4.定义、引用变量 5.指定远程主机sudo切换用户 6.when条件判断 7.迭代 8.Templates 模块 9.tags 模块 10.Roles 模块 二、实验 1.使用ansible批量安装apache服务 2.定义、引用变量…

S型曲线规划

s #include "stdio.h"typedef struct S_CTRL{ #define SSPD_BUF_LEN 100struct{float aMax;float aMin;float vMax;float J;/* 加加速度 */int t[7];int T[7];int tMax;}in;struct{float accBuf[SSPD_BUF_LEN];float decBuf[SSPD_BUF_LEN];long S[7];long V[7];}o…

电商API接口的研发和应用!

API(Application Programming Interface,应用程序编程接口)指的是为不同的软件应用程序提供编程接口的一组协议、规则以及工具的集合,以便它们能够互相交互,实现数据通信和功能调用。API已成为了现代软件开发和商业应用…