Java内存模型

主内存与工作内存

Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量包括实例变量、静态字段和构成数组对象的元素,但不包括局部变量与方法参数,因为局部变量与方法参数是线程私有的,不会被共享,不会存在竞争问题。

Java内存模型规定了所有变量都存储在主内存中。每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成,线程、主内存、工作内存三者之间的关系如下图:
在这里插入图片描述

内存间交互操作

主内存与工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,Java内存模型中定义了8种操作来完成,虚拟机实现时必须保证每一种操作都是原子的、不可再分的。8种操作如下:

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

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

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

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

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

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

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

  • write(写入)

    作用于主内存的变量,把store操作从工作内存中得到的变量值放入主内存的变量中。

Java内存模型规定在执行上面的8种基本操作时必须满足下面的规则:

  • 不允许read和load、store和write操作之一单独出现,即不允许一个变量从主内存读取了但工作内存不接受,或者从工作内存发起了回写但主内存不接受的情况出现。
  • 不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须把改变化同步会主内存。
  • 不允许一个线程无原因地把数据从线程的工作内存同步回主内存中。
  • 一个新的变量只能只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化的变量,也就是对一个变量实施use、store操作之前,必须要先执行过了assign和load操作。
  • 一个变量在同一个时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。
  • 如果对一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或者assign操作初始化变量的值。
  • 如果一个变量事先没有被lock操作锁定,那就不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定的变量。
  • 对一个变量执行unlock操作之前,必须先把此变量同步回主内存中。

volatile型变量的特殊规则

当一个变量定义为volatile之后,这个变量具备两种特性。

第一个是保证此变量对所有线程的可见性。这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。普通变量的值在线程间传递均需要通过主内存来完成,所以普通变量不能做到这一点。但这并不能保证Java操作的原子性,所以在不符合以下两条规则的运算场景中,仍然需要通过加锁来保证原子性。

  1. 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
  2. 变量不需要与其他的状态变量共同参与不变约束。

第二个是禁止指令重排序优化,普通变量仅仅会保证在该方法执行的过程中所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。

原子性、可见性与有序性

原子性由Java内存模型来直接保证,能够保证原子性的操作有read、load、assign、use、store和write。如果应用场景需要一个更大范围的原子性保证,可以使用lock和unlock操作来满足这种需求。

可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性的。

有序性,如果在本线程内观察,所有的操作都是有序的,即线程内表现为串行;如果在一个线程中观察另一个线程,所有的操作都是无序的,即指令重排序现象和工作内存与主内存同步延迟现象。

先行发生原则

先行发生是Java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生与操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等。在Java内存模型中有一些“天然的”先行发生关系,这些先行发生关系无需任何同步器协助就已经存在,可以在编码中直接使用。这些关系如下:

  • 程序次序规则

    在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确的说,应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。

  • 管程锁定规则

    一个unlock操作先行发生于后面对同一个锁的lock操作。这里必须是同一个锁。

  • volatile变量规则

    对一个volatile变量的写操作先行发生于后面对这个变量的读操作,后面指的是时间上的先后顺序。

  • 线程启动规则

    Thread对象的start()方法先行发生于此线程的每一个动作。

  • 线程终止规则

    线程中的所有操作都先行发生于对此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行。

  • 线程中断规则

    对线程interrupt()方法调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。

  • 对象终结规则

    一个对象的初始化完成先行发生于它的finalize()方法的开始。

  • 传递性

    如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

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

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

相关文章

什么是DMA?DMA究竟有多快!

原文来自公众号:工程师看海 直接内存访问(Direct Memory Access,DMA):在计算机体系结构中,DMA 是一种数据传输方式,允许外部设备直接访问计算机的内存,而无需通过中央处理单元&#…

网络防御保护---防火墙USG6000V接口配置实验

一、实验拓扑 二、实验要求 1.防火墙向下使用子接口分别对应生产区和办公区 2.所有分区设备可以ping通网关 三、实验思路 1、配置各设备的IP地址 2、划分VLAN及VLAN的相关配置 3、配置路由及安全策略 四、实验配置 4.1、配置各设备IP地址 PC1配置 Client1配置 PC2配置…

maven搭建编程环境

Maven – Download Apache Mavenmaven下载官网地址下载后解压,配置系统环境变量, 新建系统变量,在系统path中配置%MAVEN396_HOME%\bincmd中输入mvn -version查询是否成功配置本地仓库地址 创建一个本地文件夹当做本地仓库,名字可以…

应用机器学习的建议 (Advice for Applying Machine Learning)

1.决定下一步做什么 问题: 假如,在你得到你的学习参数以后,如果你要将你的假设函数放到一组 新的房屋样本上进行测试,假如说你发现在预测房价时产生了巨大的误差,现在你的问题是要想改进这个算法,接下来应…

CMS如何调优

业务JVM频繁Full GC如何排查 原则是先止损,再排查。 FGC的原因是对象晋升失败或者并发模式失败,原因都是老年代放不下晋升的对象了。 1.可能是大对象导致的内存泄漏。快速排查方法:观察数据库网络IO是否和FGC时间点吻合,找到对应…

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测,预测新数据

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测,预测新数据 目录 碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测,预测新数据预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现LSTM长短期记忆神经网络多输入单输出未来…

推荐收藏!48道数据分析师高频面试题汇总!

大家好,最近很多小伙伴私信我,讲一下数据分析的面试题,今天给大家整理了48道数据分析师面试时被频繁问到的题目,找数据分析岗位的同学一定要码住认真看。 想了解最新的面试动态、最新高频考点、技术交流的同学,可以文…

别不信❗️你离数据专家只差一个CDMP证书

1⃣️为什么选择CDMP证书? 🌟🌟亲爱的朋友们,如果你在寻找一个能让你在数据管理领域大展拳脚的证书,那么CDMP(Certified Data Management Professional)证书就是你的不二之选!&#…

西瓜书读书笔记整理(十二) —— 第十二章 计算学习理论(上)

第十二章 计算学习理论(上) 12.1 基础知识12.1.1 什么是计算学习理论(computational learning theory)12.1.2 什么是独立同分布(independent and identically distributed, 简称 i . i . d . i.i.d. i.i.d.&#xff0…

一键拥有你的GPT4

这几天我一直在帮朋友升级ChatGPT,现在已经可以闭眼操作了哈哈😝。我原本以为大家都已经用上GPT4,享受着它带来的巨大帮助时,但结果还挺让我吃惊的,还是有很多人仍苦于如何进行升级。所以就想着写篇教程来教会大家如何…

响应拦截器的 return Promise.reject(res.data.message)

今天在看老师讲解代码的时候,解决了我心中的一些疑惑。 在做excel文件导出的时候,没有告诉浏览器文件的格式是Blod产生了报错。 看下图: 可以看到下面的内容:如果业务成功 返回 res.data 如果业务失败,给出错误信息的提示,将这个错误抛出去。 因此我们在发送一个…

基于springboot+vue的网上租赁系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

鸿蒙开发案列一

1、开发需求 案例app一打开是“Hello world” 界面,开发者点击“Hello world”变成“Hello ArkUI”’ 2、源代码 Entry Component struct Hello {State person_name: string Worldbuild() {Row() {Column() {Text(Hello this.person_name).fontSize(50).fontWei…

PMP证书要怎么考,含金量怎么样?

PMP含金量更多的是“敲门砖”作用,公司招聘的门槛,现在坐项目的大部分都需要PMP/NPDP证书。 当然现在PMP管理模式也很热门,对企业发展很有利,各大企业都有引进改良应用在公司的项目上,之前在校友群里面大家在讨论PMP …

ESP8266模块WIFI功能Deauther及Evil-Twin实验过程

1.下载ESP8266Flasher及deauther2.1.0_1mb.bin这个固件 2.连接ESP8266模块到电脑 设备管理器可看到成功连接的ESP8266设备 3.开始刷入固件到ESP8266模块 运行ESP8266Flasher并点击Config选择固件: 配置高级选项: 点击Flash开始刷入固件,固件成功刷入如下: 按一下ESP8266模块…

操作系统导论-课后作业-ch14

1. 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h>int main() {int *i NULL;free(i);return 0; }执行结果如下&#xff1a; 可见&#xff0c;没有任何报错&#xff0c;执行完成。 2. 执行结果如下&#xff1a; 3. valgrind安装使用参考&a…

保姆级教程: GPTs接入广告到提现成功全过程真实记录

因为相信&#xff0c;所以看见 &#x1f31f; 1月19日&#xff0c;在AI社群首次了解到GPTs能通过接入广告获得收益。虽然对收益的多少和提现的可行性有所疑问&#xff0c;但我还是立刻在我的GPTs上尝试了这一功能。这一探索的旅程&#xff0c;如同跨入了一个未知的新世界。我的…

【江科大】STM32:旋转编码器接口

Encoder Interface 编码器接口 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减从而指示编码器的位置、旋转方向和旋转速度 &#xff08;PWM就是通计时器计次达到测频率的目的&#xff0c;而…

电脑文件mfc140.dll丢失的解决方法指导,怎么快速修复mfc140.dll

mfc140.dll 文件的缺失是个普遍的问题&#xff0c;在日常使用中可能会时不时遇到。本文主要目的是详细介绍一旦遇到 mfc140.dll 文件缺失&#xff0c;应该如何进行下载和安装的步骤。不再赘言&#xff0c;下面就一起深入了解mfc140.dll丢失的解决方法指导。 一. mfc140.dll的作…

【Java程序员面试专栏 专业技能篇】MySQL核心面试指引(三):性能优化策略

关于MySQL部分的核心知识进行一网打尽,包括三部分:基础知识考察、核心机制策略、性能优化策略,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 本篇Blog为第三部分:性能优化策略,子节点表示追问或同级提问 读写分离 分布式数据库的…