Java内存模型(JMM)详解!

news2024/11/17 10:30:37

文章目录

    • 什么是JMM?
    • 现代计算机内存模型
    • 缓存一致性
    • JMM内存模型与计算机内存模型的关系
    • 线程间通信
    • JMM三大问题
      • 原子性
      • 可见性
      • 有序性

什么是JMM?

JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。 JMM可以理解为是一个规范,一个抽象概念,并不真实存在。

现代计算机内存模型

现代计算机中,CPU的指令速度远远超过内存的存取速度,由于计算机的存储设备与CPU的运算速度有几个数量级的差距,所以现在计算机中都不得不加入一层读写速度尽可能接近CPU运算速度的高速缓存(cache)来作为内存和CPU之间的缓冲。

基于高速缓存的存储交互很好的解决了CPU和内存的速度的矛盾,但也引入了一个新的问题,缓存一致性,在多处理器系统中,每个CPU都有自己的高速缓存,而他们又共享同一主内存,当多个处理器运算任务都涉及到同一块主内存区域时,将可能导致各自的缓存数据不一致。为了解决这个问题,需要各个处理器在访问内存时,需要遵循一些协议,例如MSI、EMSI、MOSI等。

图片

缓存一致性

为了解决这个问题,先后有过两种办法

总线锁机制

总线锁就是使用CPU提供的一个LOCK#信号,当一个处理器在总线上输出此信号,其他处理器的请求将被阻塞,那么该处理器就可以独占共享锁。这样就保证了数据一致性。

缓存锁机制

但是总线锁定开销太大,我们需要控制锁的力度,所以又有了缓存锁,核心就是缓存一致性协议,不同的CPU硬件厂商实现方式稍有不同,有MSI、MESI、MOSI等。

JMM内存模型与计算机内存模型的关系

JVM虚拟机是一种抽象化的计算机,同计算机一样,它有着自己的一套完善的硬体架构,如处理器、堆栈、寄存器、操作指令等,而在JVM篇中也讲到过虚拟机栈,虚拟机栈是用于描述java方法执行的内存模型,因此JMM也是属于JVM的一部分,只是JMM是一种抽象的概念,是一组规则,并不实际存在。所不同的是,JMM模型定义的内存分为工作内存和主内存,工作内存是从主内存拷贝的副本,属于线程私有。当线程启动时,从主内存中拷贝副本到工作内存,执行相关指令操作,最后写回主内存。

图片

线程间通信

为了更好的控制主内存和本地内存的交互,Java 内存模型定义了八种操作来实现

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

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

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

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

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

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

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

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

在这里插入图片描述

JMM对这八种指令的使用,制定了如下规则:

  • 不允许read和load、store和write操作之一单独出现。即使用了read必须load,使用了store必须write

  • 不允许线程丢弃他最近的assign操作,即工作变量的数据改变了之后,必须告知主存

  • 不允许一个线程将没有assign的数据从工作内存同步回主内存

  • 一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是对变量实施use、store操作之前,必须经过assign和load操作

  • 一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁

  • 如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值

  • 如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量

  • 对一个变量进行unlock操作之前,必须把此变量同步回主内存

JMM三大问题

原子性

一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。

如何解决

  • synchronized
  • Lock锁
  • 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作
  • JDK提供了很多原子操作类来保证操作的原子性,例如基础类型:AtomicInteger,引用类型AtomicReference等。

可见性

在多线程环境下,一个线程对共享变量的修改,不仅要对本线程可见,而且要对其他线程可见。

如何解决

  • synchronized
  • Lock锁
  • JDK提供了很多原子操作类来保证操作的原子性,例如基础类型:AtomicInteger,引用类型AtomicReference等。
  • volatile: 使用volatile关键字修饰一个变量可以保证变量的可见性

volatile如何保证可见性

  • 线程对共享变量的副本做了修改,会立刻刷新最新值到主内存中。
  • 线程对共享变量的副本做了修改,其他其他线程中对这个变量拷贝的副本会时效;
  • 其他线程如果需要对这个共享变量进行读写,必须重新从主内存中加载。

有序性

程序执行的顺序按照代码的先后顺序执行

如何解决

  • happens-before原则: happens-before原则是java内存模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,也就是说发生操作B之前,操作A产生的影响能被操作B观察到。这里的“影响”包括修改共享变量,方法调用。详细的happens-before说明请参看happens-before原则章节。

  • synchronized机制: synchronized能够保证有序性是因为synchronized可以保证同一时间只有一个线程访问代码块,而单线程环境下,JMM能够保证代码的串行语义;虽然使用synchronized的代码块,还可以发生指令重排序,但是synchronized可以保证只有一个线程执行,所以最后的结果还是正确的。

  • volatile机制: volatile的底层是使用内存屏障来保障有序性的。写volatile变量时,可以确保volatile写之前的操作不会被编译器重排序到volatile写之后。读volatile变量时,可以确保volatile读之后的操作不会被编译器重排序到volatile读之前。

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

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

相关文章

Java 单元测试

目录 一、Junit 1.1、单元测试初始化与清理资源 1.2、捕获异常 1.3、条件测试 1.4、标记失效测试方法 1.5、参数化测试 单元测试:是对最小功能单元编写的测试代码。 示例,当开发好一个 Java 阶乘的方法。 n! 1 x 2 x 3 x ..…

CRM软件哪个好?该如何选择?

CRM软件哪个好?该如何选择? CRM是集营销、销售、服务为一体的围绕客户全生命周期管理的系统,在各行各业的数字化转型大潮中,作为以消费者、终端用户、客户为主导的企业经营管理核心系统,CRM选型的难度和复杂度也在不断…

关于ETL的两种架构(ETL架构和ELT架构)

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象…

Java的JVM垃圾回收机制GC概述

JVM——GC机制1、什么是GC?2、GC算法的总体概述3、JVM所处的位置4、JVM整体结构5、JVM架构模型6、Java垃圾回收机制优缺点7、GC主要关注的区域垃圾回收算法:标记阶段,引用计数循环引用标记阶段:可达性分析算法GC root可以是哪些&a…

JavaScript代码题--以及一些奇奇怪怪的发现

解析 let a{b:10,c:{d:[11,12],e:13}},实现 10111213 效果 解 const a{b:10,c:{d:[11,12],e:13}}function sum(obj) {let total 0;const value Object.values(obj)value.forEach(item>{total typeof item number ? item : sum(item)})return total }const …

Java家教系统家教网站家教兼职系统

简介: 用户可以注册成为学员也可以是教员。教员发布家教信息,学员根据自己的要求查找符合自己的教员。学员预约教员的某一天去家教,教员可以在个人中心里查看,是否接受该预约。在教员接受或拒绝之前,学员随时可以取消…

数据库,计算机网络、操作系统刷题笔记23

数据库,计算机网络、操作系统刷题笔记23 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle…

基于 Vue 制作一个猜拳小游戏

目录前言:项目效果展示:对应素材:代码实现思路:实现代码:总结:前言: 在工作学习之余玩一会游戏既能带来快乐,还能缓解生活压力,跟随此文一起制作一个小游戏吧。 描述&…

【2042. 检查句子中的数字是否递增】

来源:力扣(LeetCode) 描述: 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个…

ORA-00600 kcratr_nab_less_than_odr 问题处理

问题:ORA-00600: 内部错误代码, 参数: [kcratr_nab_less_than_odr], [1], [196495], [39399], [39460], [], [], [], [], [], [], []导致原因:可能是由于服务器宕机,控制文件的缺失,或者在线日志文件在实例恢复时不完整1、数据库未…

5G边缘计算网关助力5G工业物联网智能化建设

5G边缘计算,凭借高带宽、高可靠、低时延、移动性等特性,推动工业生产物联网发展趋势,实现工业更快、更精准通信及数据共享。边缘计算网关下5G工业物联网远程感知生产一线,工控数字化、自动化、智能化,降低人物力资源成…

LeetCode 2042. 检查句子中的数字是否递增

【LetMeFly】2042.检查句子中的数字是否递增 力扣题目链接:https://leetcode.cn/problems/check-if-numbers-are-ascending-in-a-sentence/ 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 tok…

【计算机体系结构】指令集并行(ILP)动态调度算法:Tomasulo实现代码(Tomasulo Algorithm Implementation)

Tomasulo Algorithm Implementation (本文章仅提供算法实现过程,具体算法思想请查阅教科书) 如果觉得这篇文章有用,请记得点个赞并收藏哦! 1.Introduction Tomasulo算法用于指令的动态调度,允许乱序执行…

C C++内存对齐以及特殊类的大小

目录C语言内存对齐现象内存对齐规则为什么存在内存对齐如果struct or class中存在成员函数时的大小空类大小为1Cclass存在虚函数时的大小C语言 内存对齐现象 C语言中结构体的大小往往不是结构体中各种数据类型的加和,因为存在内存对齐; struct S {double d;//8字…

Linux常用系统日志

文章目录一 常用系统日志二 系统日志优先级三 其他日志文件一 常用系统日志 日志文件用途/var/log/messages记录大多数系统日志信息,包括启动、IO错误、网络和程序等问题/var/log/secure记录安全和身份验证等相关消息和错误/var/logrsyslog将所有日志文件写入到该目…

Nacos 漏洞利用

Nacos 漏洞利用 1.漏洞描述: Alibaba Nacos是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。致力于帮助发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,可以快速实现动态…

ASP.NET企业智能办公OA系统源码带文档【源码免费分享】

ASP.NET企业智能办公OA系统源码带文档 需要源码学习可私信我获取! 本系统特色功能: 1:自定义工作流程,系统所有参数可自定义配置,支持多分公司、多部门架构 2:采用三层结构设计软件,系统扩容性…

vivo 实时计算平台建设实践

作者:vivo 互联网实时计算团队- Chen Tao 本文根据“2022 vivo开发者大会"现场演讲内容整理而成。 vivo 实时计算平台是 vivo 实时团队基于 Apache Flink 计算引擎自研的覆盖实时流数据接入、开发、部署、运维和运营全流程的一站式数据建设与治理平台。 一、v…

【云边有个小卖部】阅读笔记

童年就像童话,这是他们在童话里第一次相遇。 那么热的夏天,少年的后背被女孩的悲伤烫出一个洞,一直贯穿到心脏。 刘十三被欺负得最惨,却想保护凶巴巴的程霜。 每当她笑的时候,就让他想起夏天灌木丛里的萤火虫&#xff…

2022年专业连锁行业研究报告

第一章 行业概况 专业连锁经营是一种商业组织形式和经营制度,是指经营同类商品或服务的若干个企业,以一定的形式组成一个联合体,在整体规划下进行专业化分工,并在分工基础上实施集中化管理,把独立的经营活动组合成整体…