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

JAVA内存模型(JMM)
共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。
上面的工作内存其实是java内存模型抽象出来的概念,下面简要介绍一下java内存模型(JMM)。
java内存模型(java memory model): 描述了java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节。
不同的平台,内存模型是不一样的,我们可以把内存模型理解为在特定操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。Java 虚拟机规范中试图定义一种 Java 内存模型(Java Memory Model,简称 JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果,不必因为不同平台上的物理机的内存模型的差异,对各平台定制化开发程序。
更具体一点说,Java 内存模型提出目标在于,定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

从上图可以得出结论:
所有的变量都存储在主内存中每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存该变量的一份拷贝)。
JMM关于synchronized的两条规定:
- 线程解锁前,必须把
共享变量的最新值刷新到主内存中 - 线程加锁时,将
清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值。(加锁和解锁需要是同一把锁)
线程解锁前对共享变量的修改在下次加锁前对其他线程可见。
JVM主内存与工作内存描述
JVM将内存为主内存和工作内存两个部分。
主内存: 主要包括本地方法区和 堆
- Java 内存模型规定了
所有变量都存储在主内存(Main Memory)中(此处的主内存与介绍物理硬件的主内存名字一样,两者可以互相类比,但此处仅是虚拟机内存的一部分)。
工作内存: 每个线程都有一个工作内存,工作内存中主要包括两个部分,一个是属于该线程私有的栈和 对主存部分变量拷贝的寄存器(包括程序计数器PC和cup工作的高速缓存区)。
- 每个线程都有自己的
工作内存(Working Memory,又称本地内存.),线程的工作内存中保存了该线程使用到的变量,该变量是主内存中的共享变量的副本拷贝。 - (工作内存是 JMM 的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。)

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

1、所有的变量都存储在主内存中(虚拟机内存的一部分),对于所有线程都是共享的
2、每个线程都有自己的工作内存,工作内存中保存的是主存中某些变量的值的副本拷贝,线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存中的变量。
3、线程之间无法直接访问对方的工作内存中的变量值的,线程间变量的传递均需要通过主内存来完成。
这种划分与Java运行时内存区域中堆、栈、元空间等的划分是不同层次的划分,两者基本没有关系。硬要联系的话,大致上主内存对应Java堆中对象的实例数据部分、工作内存对应栈的部分区域;从更低层次上说,主内存对应物理硬件内存、工作内存对应寄存器和高速缓存。
JVM内存间交互规则
关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,Java 内存模型中定义了下面 8 种操作来完成。
- Lock(锁定):作用于主内存中的变量,把一个变量标识为被一个线程独占的状态。
- Unlock(解锁):作用于主内存中的变量, 将一个变量从锁定状态(Lock)释放出来,释放后的变量才可以被其他线程锁定(Lock)
Read(读取):作用于主内存中的变量,将一个变量的值从主内存传输到工作内存中,以便随后的load操作使用Load(加载):作用于工作内存中的变量,把read操作从主内存中得到的变量的值放入工作内存的变量副本中。- Use(使用):作用于工作内存中的变量,把工作内存中一个变量的值传递给执行引擎。(每当虚拟机遇到一个需要使用到变量的值的字节码指令时就会执行这个操作。)
- Assign(赋值):作用于工作内存中的变量,把一个从执行引擎接收到的值赋值给工作内存中的变量。(每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。)
Store(存储):作用于工作内存中的变量,把工作内存中的一个变量的值传送到主内存中,以便随后 write 操作使用。Write(写入):作用于主内存中的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中。
需知:
- 在将变量从主内存读取到工作内存中,必须顺序执行
read(读取)、load(加载); - 要将变量从工作内存同步回主内存中,必须顺序执行
store(存储)、write(写入)。
这8种操作必须遵循以下规则:
-
不允许
read(读取)和load(加载)、store(存储)和write(写入)操作之一单独出现。即不允许一个变量从主内存被读取了,但是工作内存不接受,或者从工作内存回写了但是主内存不接受。不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步会主内存中
-
不允许一个线程丢弃它最近的一个
assign(赋值)操作,即变量在工作内存被更改后必须同步改更改回主内存。即:执行store(存储),write(写入)操作 -
工作内存中的变量在没有执行过
assign(赋值)操作时,不允许无意义的同步回主内存。 即:执行store(存储),write(写入)操作 -
在执行
use(使用)前必须已执行load(加载),在执行store(存储)前必须已执行assign(赋值)。 -
一个变量在
同一时刻只允许一个线程对其执行lock操作,一个线程可以对同一个变量重复执行多次lock,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现。 -
一个线程在
lock一个变量的时候,将会清空工作内存中的此变量的值,执行引擎在use(使用)前必须重新read(读取)和load(加载)初始化变量的值。 -
在执行
unlock之前,必须首先执行了store(存储)和write(写入)操作对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)
-
线程不允许
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博客
相关文章:
java八股文面试[多线程]——主内存和工作内存的关系
JAVA内存模型(JMM)共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。 上面的工作内存其实是java内存模型抽象出来的概念,下面简要介绍一下java内存模型(JMM&…...
技术分享 | LSM,Linux 内核的安全防护盾
计算机安全是一个非常重要的概念和主题,它不仅仅可以保护用户个人信息和资产的安全,还可以影响到用户在使用过程中的体验;但同时,它也是一个很抽象的概念,关于其相关文献和资料不计其数,但它究竟是什么、包…...
http服务(Apache 2.4.57)源码编译及使用
这里安装的是Apache 2.4.57版本 1.下载源码包及编译安装 下载地址 # 下载 wget https://archive.apache.org/dist/httpd/httpd-2.4.57.tar.gz # 如果系统自带httpd这个软件要删除掉,两个软件不能同时运行 rpm -e httpd --nodeps # 安装依赖环境 yum -y install apr apr-dev…...
【1day】H5S视频平台未授权漏洞学习
目录 一、漏洞描述 二、资产测绘 三、漏洞复现 四、漏洞修复 一、漏洞描述 H5S视频平台是一个基于Web技术的视频播放和流媒体管理平台。它提供了一套完整的解决方案,用于在网页上播放和管理视频内容。H5S视频平台存在未授权漏洞,泄露内网rtsp服务集群的服务集群的和H5_…...
企业架构LNMP学习笔记3
服务器基本环境配置: 1、安装虚拟机,centos7.9 操作系统; 2、网络配置; 3、机器名FQDN设置; 4、DNS解析设置,本地hosts设置; 5、配置yum源环境; 6、vim安装配置; …...
使用Spring Boot和Kafka实现消息发送和订阅
文章目录 一,新建Spring Boot1,Maven配置2,无法识别为SpringBoot项目3,无效的源发行版4,无法访问SpringApplication5,运行直接Finish6,服务运行成功 二,安装启动Kafka1,下…...
探讨uniapp的组件使用的问题
1 视图容器 1.1 view Flex是Flexible Box的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性。 当设置display: flex后,继续给view等容器组件设置flex-direction:row或column,就可以在该容器内按行或列排布子组件。uni-ap…...
【跟小嘉学 Rust 编程】十七、面向对象语言特性
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...
mall :rabbit项目源码解析
文章目录 一、mall开源项目1.1 来源1.2 项目转移1.3 项目克隆 二、RabbitMQ 消息中间件2.1 rabbit简介2.2 分布式后端项目的使用流程2.3 分布式后端项目的使用场景 三、安装RabbitMQ(Win10)3.1安装erLang语言,配置环境变量3.2 安装RabbitMQ服务端3.3 测试安装效果 四…...
JDBC连接数据库
目录 一.什么是JDBC 二.JDBC的实现步骤 三.简单使用JDBC 一.什么是JDBC JDBC是Java数据库连接,是java中提供数据库访问的Java API,它为关系型数据库的提供了统一访问规范。 二.JDBC的实现步骤 1.创建数据库连接 这里有两种方式: DataSource创建,提…...
Linux学习之Ubuntu 20中OpenResty的nginx目录里内容和配置文件
参考的文章是《nginx配置详解》 可以参考我以前的文章安装OpenResty。 cd /usr/local/openresty切换目录,ls -l查看目录里边的内容。 我的系统中,nginx目录是/usr/local/openresty/nginx,在这个目录里边有一些目录,如下ÿ…...
使用axi_quad_spi操作spi_flash
文章目录 基本测试情况IP支持的命令 基本测试情况 有spi_flash需要访问,为简单计,选择使用axi_quad_spi进行操作。开始时,将IP配置成如下参数, 这样配置,是想着能够适应各家的FLASH(实际使用的则是micron…...
Linux:tomcat (源码包安装)(官网下载-安装-启动-配置-等等等-----从入门到入土)
介绍 Apache Tomcat软件是一个开源实现 Jakarta Servlet、Jakarta Server Pages、Jakarta Expression Language、Jakarta WebSocket、Jakarta Annotations 和 Jakarta Authentication 规范。 这些规范是Jakarta EE平台的一部分。 Apache Tomcat软件是在开放和参与式中开发的。 …...
中科驭数以DPU先进计算技术,夯实下一代金融IT基础设施底座
由中国计算机学会主办的第19届CCF全国高性能计算学术年会(CCF HPC China 2023)于8月23日至26日在青岛成功召开。在“高性能金融计算”主题论坛上,中科驭数高级副总裁、CTO卢文岩应邀发表了题为《DPU先进计算技术助力下一代交易底座》的演讲&a…...
Android 手游聚合SDK小知识(二) 聚合分包
更新: 在上一篇文章中,我们介绍了如何聚合SDK的基本原理,介绍了聚合SDK的接口设计,那么当CP接入了我们的聚合SDK,给了我们游戏apk包时,这时我们又当如何分发渠道包呢? 分发渠道包:…...
【RISC-V】RISC-V寄存器
一、通用寄存器 32位RISC-V体系结构提供32个32位的整型通用寄存器寄存器别名全称说明X0zero零寄存器可做源寄存器(rs)或目标寄存器(rd)X1ra链接寄存器保存函数返回地址X2sp栈指针寄存器指向栈的地址X3gp全局寄存器用于链接器松弛优化X4tp线程寄存器常用于在OS中保存指向进程控…...
Python爬虫异常处理实践:处理被封禁和网站升级问题
在这篇文章中,我们将一起探讨Python爬虫异常处理实践,特别关注处理被封禁和网站升级问题。让我们一起来看看如何解决这些问题,提高我们爬虫程序的稳定性和可靠性。 首先,我们要了解为什么会遇到这些问题。网站封禁爬虫的原因主…...
重大工程建造云服务平台源码 SpringCloud+Vue
技术架构: 微服务JavaSpring Cloud VueUniApp MySql 开发语言:Java 开发工具:Idea 前端框架:Vue 后端框架:Spring Cloud 数 据 库:MySql 移 动 端:UniApp 系统端口:PC端&…...
MyBatisPlus简单入门
1、简单介绍MyBatisPlus MyBatisPlus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,完全去SQL化,封装好了大量的CRUD操作。甚至吧CRUD操作封装到了Service层,可以直接在Controller调用现成的CRUD服务层,…...
神经网络入门
神经网络的基本骨架 1. nn.Module的使用 所有的模型都要继承 Module 类需要重写初始化函数和运算步骤函数 eg: import torch.nn as nn import torch.nn.functional as Fclass Model(nn.Module): # 继承父类Module def __init__(self): # 重写初始化函数super()…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
