JMM以及三大特性

JMM的三大特性、八大原子操作、happens-before原则 本文深入解析了Java内存模型(JMM)的核心概念。首先介绍了JMM三大特性:原子性(通过synchronized和原子类实现)、可见性(volatile/synchronized/final保证)和有序性(通过happens-before原则和内存屏障实现)。其次详细阐述了数据同步的八大原子操作(lock/unlock/read/load/use/store/write)及其流程。重点讲解了happens-before原则的八条规则及其在并发编程中的实际意义,包括解决内存可见性和禁止指令重排序等问题。最后 阅读详情
  • JMM是什么?

Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各
种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效
果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可
以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。
JMM
描述的是一种抽象的概念,一组规则,通过这组规则控制程序中各个变量在共享数据区域和私
有数据区域的访问方式,JMM是围绕原子性、有序性、可见性展开的。

JMM规范

JMM规定了所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory),线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。

JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可
以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量

  • JMM的三个特征

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

原子性(Atomicity)

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

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

下面我们来演示这个32位JVM下,对64位long类型的数据的访问的问题:

可见性:

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

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

无论是普通变量还是volatile变量都是如此,区别在于:volatile的特殊规则保证了volatile变量值修改后的新值立刻同步到主内存,每次使用volatile变量前立即从主内存中刷新,因此volatile保证了多线程之间的操作变量的可见性,而普通变量则不能保证这一点。

volatile写-读的内存语义
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存中
读取共享变量。

除了volatile关键字能实现可见性之外,还有synchronized,Lock,final也是可以的。

使用synchronized关键字,在同步方法/同步块开始时(Monitor Enter),使用共享变量时会从主内存中刷新变量值到工作内存中(即从主内存中读取最新值到线程私有的工作内存中),在同步方法/同步块结束时(Monitor Exit),会将工作内存中的变量值同步到主内存中去(即将线程私有的工作内存中的值写入到主内存进行同步)。

使用Lock接口的最常用的实现ReentrantLock(重入锁)来实现可见性:当我们在方法的开始位置执行lock.lock()方法,这和synchronized开始位置(Monitor Enter)有相同的语义,即使用共享变量时会从主内存中刷新变量值到工作内存中(即从主内存中读取最新值到线程私有的工作内存中),在方法的最后finally块里执行lock.unlock()方法,和synchronized结束位置(Monitor Exit)有相同的语义,即会将工作内存中的变量值同步到主内存中去(即将线程私有的工作内存中的值写入到主内存进行同步)。

final关键字的可见性是指:被final修饰的变量,在构造函数数一旦初始化完成,并且在构造函数中并没有把“this”的引用传递出去(“this”引用逃逸是很危险的,其他的线程很可能通过该引用访问到只“初始化一半”的对象),那么其他线程就可以看到final变量的值。

有序性:

对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。用一句话可以总结为:在本线程内观察,操作都是有序的;如果在一个线程中观察另外一个线程,所有的操作都是无序的。前半句是指“线程内表现为串行语义(WithIn Thread As-if-Serial Semantics)”,后半句是指“指令重排”现象和“工作内存和主内存同步延迟”现象。

一个最经典的例子就是银行汇款问题,一个银行账户存款100,这时一个人从该账户取10元,同时另一个人向该账户汇10元,那么余额应该还是100。那么此时可能发生这种情况,A线程负责取款,B线程负责汇款,A从主内存读到100,B从主内存读到100,A执行减10操作,并将数据刷新到主内存,这时主内存数据100-10=90,而B内存执行加10操作,并将数据刷新到主内存,最后主内存数据100+10=110,显然这是一个严重的问题,我们要保证A线程和B线程有序执行,先取款后汇款或者先汇款后取款,此为有序性。

Java提供了两个关键字volatile和synchronized来保证多线程之间操作的有序性,volatile关键字本身通过加入内存屏障来禁止指令的重排序,而synchronized关键字通过一个变量在同一时间只允许有一个线程对其进行加锁的规则来实现,

在单线程程序中,不会发生“指令重排”和“工作内存和主内存同步延迟”现象,只在多线程程序中出现。

  • 关键词synchronized与volatile总结

synchronized的特点
一个线程执行互斥代码过程如下:

        获得同步锁;
        清空工作内存;
        从主内存拷贝对象副本到工作内存;
        执行代码(计算或者输出等);
        刷新主内存数据;
        释放同步锁。
        所以,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。

volatile是第二种Java多线程同步的手段,根据JLS的说法,一个变量可以被volatile修饰,在这种情况下内存模型确保所有线程可以看到一致的变量值

    class Test {  
        static volatile int i = 0, j = 0;  
        static void one() {  
            i++;  
            j++;  
        }  
        static void two() {  
            System.out.println("i=" + i + " j=" + j);  
        }  
    }  

加上volatile可以将共享变量i和j的改变直接响应到主内存中,这样保证了i和j的值可以保持一致,然而我们不能保证执行two方法的线程是在i和j执行到什么程度获取到的,所以volatile可以保证内存可见性,不能保证并发有序性(不具有原子性)。
如果没有volatile,则代码执行过程如下:

        将变量i从主内存拷贝到工作内存;
        刷新主内存数据;
        改变i的值;
        将变量j从主内存拷贝到工作内存;
        刷新主内存数据;
        改变j的值;

参考链接:

JMM概述_牧竹子的博客-优快云博客_jmm

JMM内存模型 & 多线程三大特性   提起并发编程,就绕不开并发的三大特性(1.原子性、2.可见性、3.有序性);要解决并发编程中遇到的这三类问题,可能很多人也知道大名鼎鼎的 JMM 内存模型,但又有多少人知道 JMM 内存模型是如何解决这三大问题的呢?本文就从原理层面来细细讲解。   在《并发编程》板块,已经有介绍到 1.计算机原理结构   2.MESI缓存一致性协议。这两篇内容介绍的也只是在硬件CPU层面上的解决方案。在 Java 软件层面,就是我们接下来要介绍的 JMM 内存模型,JMM 内存模型就是基于 CPU 底层架构的一种抽象 阅读详情

相关推荐

PCIe 6.0实战指南:从链路训练到信号完整性的避坑手册

本文是一份针对PCIe 6.0硬件工程师的实战避坑指南。文章深入解析了从NRZ到PAM4调制带来的信号完整性挑战,详细拆解了链路训练(LTSSM)的复杂过程与调试方法,并提供了从信道仿真到实验室实测(如使用Keysight示波器进行眼图与误码率分析)的完整信号完整性闭环验证策略,帮助工程师解决高速率下的链路不稳定与降速问题。

weixin_29306875的博客 342

JMM(Java内存模型)详解

1.什么是JMM? ​ JMM 是Java内存模型( Java Memory Model),简称JMM。它本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范。通过这组规范,定义了程序中对各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 ​ 计算机在执行程序时,每条指令都是在CPU中执行的。而执行指令的过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过

LYQ20010417的博客 3万+

【干货】SAP物料分类账的简单理解

一、SAP物料分类账理解 物料分类账,简称ML(material ledger),其基本用途是可以用八个字概括“还原成本”、“还原库存”。即通过月底运行物料分类账,将库存差异(原材料-材料成本差异、库存商品-自制半成本差异、库存商品-自制产成品差异)自动按当期库存出库数和库存结存数的比例分摊至成本和库存中。为了理解其概念,可以简单举一个例子: 开一工单,生产A产品,数量为3个,当月全部生产完工

ERP运维咨询(目标和成功) 1万+

JMM概述

简介什么是JMM内存模型可以理解为在特定的操作协议下,对特定的内存或者高速缓存进行读写访问的过程抽象描述,不同架构下的物理机拥有不一样的内存模型,Java虚拟机是一个实现了跨平台的虚拟系统,因此它也有自己的内存模型,即Java内存模型(Java Memory Model, JMM)。因此它不是对物理内存的规范,而是在虚拟机基础上进行的规范从而实现平台一致性,以达到Java程序能够“一次编写,到处运行

牧竹子 6万+

【Cadence】Virtuoso@LayoutXL 差分电路版图镜像同步技巧详解

本文详细介绍了在Cadence Virtuoso LayoutXL中实现差分电路版图镜像同步的技巧,包括核心需求、环境配置、分步操作指南及高级技巧。通过使用LayoutXL的Group功能,工程师可以高效保持差分电路的对称性,提升版图迭代效率,确保高速信号处理的稳定性。特别适用于深亚微米工艺下的差分放大器设计。

weixin_29215391的博客 323

Cadence学习之路:什么是PCB工艺的正片与负片

正片??负片??Flash焊盘的创建与使用

qq_46757048的博客 4245

JVM:JMM介绍(简单明了版本)

Java 内存模型(Java Memory Model,JMM)是一种抽象的概念,并不真实存在,它是 Java 虚拟机规范中定义的一组规则,用于屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果,保证多线程环境下程序的正确性。

Bbb36921的博客 2267

手把手教你用Matlab/Simulink搭建PMSM的SMO无感FOC仿真(附相位补偿与离散化代码)

本文详细介绍了基于滑模观测器(SMO)的永磁同步电机(PMSM)无传感器FOC控制方法,通过Matlab/Simulink平台实现从理论到实践的完整流程。内容涵盖SMO核心原理、离散化处理、转子位置估算与相位补偿技术,以及双闭环控制系统搭建,为工程师提供了一套完整的无传感器控制解决方案。

weixin_27038245的博客 253

java并发编程 笔记十二

Java 内存模型 JMM 即 Java Memory Model,它定义了主存、工作内存抽象概念,底层对应着 CPU 寄存器、缓存、硬件内存、 CPU 指令优化等。 JMM 体现在以下几个方面 原子性 - 保证指令不会受到线程上下文切换的影响 可见性 - 保证指令不会受 cpu 缓存的影响 有序性 - 保证指令不会受 cpu 指令并行优化的影响 可见性 退不出的循环 先来看一个现象,main...

笨鸟先飞 382

Android开发实战:5分钟搞定全屏沉浸式状态栏(附完整代码示例)

本文提供了Android开发中实现全屏沉浸式状态栏的完整实战指南。通过对比主题配置、动态代码设置和Window标志位三种方法,详细讲解了如何隐藏状态栏并处理布局适配。文章还涵盖了刘海屏、手势导航等高级适配场景,并附有可直接使用的工具类代码,帮助开发者快速提升应用视觉体验。

weixin_29197699的博客 359

区块链入门:用账本、乐高和三台旧电脑讲懂分布式账本

区块链是一种去中心化的分布式账本技术,其核心原理是通过密码学哈希、共识机制和链式结构实现数据不可篡改与多方共同验证。它不依赖单一中心,而是将交易记录同步复制到多个节点,依靠数学规则而非人工信任达成一致,从而在数字世界构建可验证的信用基础设施。这种‘集体见证’模式显著提升了系统抗单点故障与人为干预的能力,广泛应用于供应链溯源、数字身份、教育管理及公益透明等需强信任保障的场景。本文以账本类比、乐高拆解和Ganache实操为线索,面向零基础读者通俗解析哈希值、挖矿与智能合约等关键概念。

weixin_30517215的博客 274

JMM(Java 内存模型)详解

所有线程创建的实例对象都存放在主内存中,不管该实例对象是成员变量还是方法中的本地变量(也称局部变量)每个线程都有一个私有的本地内存来存储共享变量的副本,并且,每个线程只能访问自己的本地内存,无法访问其他线程的本地内存。本地内存是 JMM 抽象出来的一个概念,存储了主内存中的共享变量副本。线程 A 把本地内存中修改过的共享变量副本的值同步到主内存中去。线程 B到主存中读取对应的共享变量的值。也就是说,JMM 为共享变量提供了可见性的保障。

m0_51431003的博客 7334

【华为OD机试真题 新系统】1043、魔法咒语组合 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 新系统】1043、魔法咒语组合 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2026e卷,od机试,2026E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2026华为od,如何备战华为od

KJ.JK 282

【JUC】十七、JMM下的三大特性

我们定义的所有共享变量都储存在物理主内存中每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝)线程对共享变量所有的操作都必须先在线程自己的工作内存中进行后写回主内存,不能直接从主内存中读写(不能越级)不同线程之间也无法直接访问其他线程的工作内存中的变量,线程间变量值的传递需要通过主内存来进行(同级不能相互访问)

llg___的博客 1078

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

JMM内存三大特性

JMM内存三大特性: 原子性(只有一个语句):基本数据类型的访问读写是具备原子性的,若如需要更大范围的原子性, 。(即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,i++等操作) 需要synchronized关键字约束或lock体系的支持 可见性:当一个线程修改了共享变量的值,其他线程能够立即得知此修改。volatile、 synchronized、fina...

qq_41832361的博客 520

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JMM模型与并发三大特性

storeLoad内存屏障 ==> (汇编层面指令)方面使用Lock指令“ lock;例如volatile,锁机制当前线程对当前共享变量的操作会存在读不到,或者不能立刻感知另一个线程对共享变量的写操作通过上下文切换,例如Thread.yield();

子墨将的博客 296

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JAVA并发三大特性及JMM模型理解

并发编程Bug根源:原子性、可见性、有序性。

HelloMyAndYourWorld的博客 1015

并发编程之JMM模型和并发三大特性

1. JMM模型 JMM内存模型是java虚拟机提出的一种规范,用来协调操作系统与硬件的各种差异,实现并发效果。 其中有8种原子指令: 1.lock:锁定变量 2.unlock:解锁锁定的变量,当锁定多次时需要解锁同样次数,锁定与解锁必须成对出现 3. read,load:从主内存读取变量值加载到本地内存,两个原子指令必须顺序执行 4. use:将本地内存中的变量值给执行引擎,随时给线程使用 5. assign:将执行引擎的值赋值给本地内存 6. store,write:从本地内存存储变量

qq_21575929的博客 5788

JMM 如何保证并发编程的三大特性

一点睛 并发编程的三大特性是原子性、可见性和顺序性。 JVM采用内存模型的机制来屏蔽各个平台和操作系统之间内存访问的差异,以实现让Java程序在各个平台下达到一致的内存访问效果,比如C语言中的整型变量,在某些平台下占用了两个字节,在某些平台下占用了四个字节的内存,但Java则在任何平台下,int类型就是四个字节,这就是所谓一致内存访问效果。 Java的内存模型规定了所有变量都是存在于主内存(RAM)当中的,而每个线程都有自己的工作内存或者本地内存(这一点像CPU的Cache)...

实践求真知 603

并发编程三大特性与JMM内存模型核心笔记

摘要:本文系统解析了Java并发编程的三大核心特性——原子性、可见性和有序性。原子性问题表现为复合操作被中断(如i++),可通过synchronized、Lock或CAS解决;可见性问题源于线程本地内存与主存不一致,需借助volatile或同步机制;有序性问题由指令重排序引发,需使用volatile禁止特定重排。文章深入剖析了Java内存模型(JMM)的抽象结构、八种原子操作及内存屏障实现原理,并详解happens-before原则的八大规则。最后通过对比表格总结不同特性的解决方案,建议简单场景用synch

慢慢 562

深入理解JMM以及并发三大特性

并发和并行的单核处理器,但是,使得宏观上具有多个进程同时执行的效果,但是微观上并不是同时执行的,只是把时间段分成若干段,使多个进程快速交替的执行: 并发解决什么问题: 并行在多核处理器系统中存在,而并发在单核和多核处理器中都存在并发的三大特性出现线程安全问题的原因: Thread.yield()能保证可见性吗: ,即便使用Thread.yield()释放CPU时间片,也会认为while优先级最高,导致while的效果看起来一直占用CPU时间片,这样有种,如果核数有限,优先级比较低的线程抢占不到时间片,就可能

Moonxiyue的博客 365

Java高并发之JMM(java内存模型、volatile变量、JMM的三大特性)

1. Java内存模型概述 ① 常见的并发应用场景 常见的并发应用场景: 多任务处理:* 计算机中,CPU的运算速度和它的存储和通信子系统的速度差异很大。为了充分利用CPU资源,让CPU同时处理多个任务。 服务器: 服务器可以同时为多个客户端提供服务 ② 如何充分利用CPU资源? 高速缓存(Cache) 为了解决CPU和内存之间的速度差异,避免慢的内存影响快的CPU,在CPU和内存...

lucyLee的博客 708

JUC---JMM之三大特性、八大原子操作、happens-before原则

在 Java 内存模型(JMM)规范下,有三大特性,分别是原子性、可见性、有序性

Elmer的博客 2809

深入理解JMM和并发三大特性

其缺点是窥探是不可扩展的。而基于目录的机制延迟较高,但使用更少的带宽,因为消息是点对点的,而不是广播的,因此许多较大的系统(>64位处理器)使用这种类型的缓存一致性。缓存锁定是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作协会内存时,处理器不会在总线上发出LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会组织同时修改由两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时,会使该缓存行无效。

博客 376

Java的内存模型JMM的三大特性

两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法。指程序执行的顺序按照代码的逻辑顺序执行。如果一个操作先行发生另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。指一个操作或多个操作要么全部执行完成,要么都不执行,中间不会被其他线程打断,操作过程不可分割。

m0_63243718的博客 492

并发编程一:深入理解JMM和并发三大特性(上)

文章目录深入理解JMM和并发三大特性(上)前言并发编程三特性JMM内存模型可见性深入分析总结 深入理解JMM和并发三大特性(上) 前言 JMM属于整个Java并发编程中最难的部分也是最重要的部分(JAVA多线程通信模型——共享 内存模型),涉及的理论知识比较多,我会从三个维度去分析: JAVA层面、JVM层面 、硬件层面。 在了解JMM和并发编程之前先来看看什么是并发,多线程有什么作用,并发编程出现bug的根本原因是什么。 并发和并行 并发和并行目标都是最大化CPU的使用率 并行(parallel):指在同

admin522043032的博客 1424
上一篇: HashMap小结
下一篇: linux常用命令
Learning_foolish
博客等级 码龄9年 14粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值