Java内存模型(JMM)是一套抽象规则,而非物理内存结构,核心定义“主内存”与“工作内存”的交互规范:主内存为线程共享区域,存储实例变量、静态变量等;工作内存为线程私有副本空间,所有变量操作必须在此进行并同步回主内存。

Java 内存模型(JMM)不是物理内存结构,而是一套用于规范多线程环境下共享变量访问行为的抽象规则。它的核心在于“主内存”与“工作内存”的分工与协作——所有可见性、原子性和有序性问题,都源于这两个逻辑区域之间如何传递数据。
主内存和工作内存到底是什么
主内存是所有线程共享的逻辑区域,存储实例字段、静态变量、数组元素等共享变量;它大致对应 JVM 堆和方法区中存放的数据。工作内存则是每个线程私有的逻辑空间,不对应某一块真实内存,而是对线程操作变量时所用副本的抽象描述——可能体现为 CPU 寄存器、L1/L2 缓存、写缓冲区,甚至编译器优化后的临时存储。
关键点在于:工作内存不是 JVM 运行时数据区中的某个具体部分(比如虚拟机栈),也不是 CPU 缓存的直接映射,而是一种为了定义交互规则而引入的逻辑概念。
例如,static int count = 0 存在主内存中;线程 A 执行 count++ 时,并不能直接修改主内存里的值,必须先将 count 的当前值从主内存读入自己的工作内存,再计算,最后写回主内存。
立即学习“Java免费学习笔记(深入)”;
变量交互必须经过八种原子操作
JMM 规定了八个不可分割的基本操作,来严格约束主内存与工作内存之间的数据流动:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- read:从主内存读取变量值
- load:把 read 得到的值放入工作内存变量副本
- use:把工作内存变量值传给执行引擎(如参与运算)
- assign:把执行引擎返回的结果赋给工作内存变量
- store:把工作内存变量值传送到主内存
- write:把 store 传来的值写入主内存变量
- lock:对主内存变量加锁,标识为线程独占
- unlock:释放主内存变量锁
这些操作需满足特定约束,比如 read 和 load 必须连续执行,中间不能插入其他操作;store 和 write 同理。违反规则就可能导致一个线程修改了变量,另一个线程却看不到最新值。
为什么不能直接操作主内存
线程不能绕过工作内存直接读写主内存,这是 JMM 设计的关键前提。它强制所有共享变量的操作都在本地副本上进行,再通过显式同步机制回写,从而为可见性控制提供基础。
这种设计屏蔽了底层硬件差异(如多核 CPU 缓存不一致、指令重排序),让 Java 程序在不同平台表现一致。如果没有这层抽象,程序员就得针对每种 CPU 架构手动处理缓存刷新、内存屏障等细节。
也正因如此,普通变量的修改不保证立即被其他线程看到;要实现可靠通信,必须借助 volatile、synchronized 或 final 等机制,它们通过影响上述八种操作的执行顺序或可见性,来建立 happens-before 关系。
JMM 与 JVM 内存区域不是一回事
很多人混淆 JMM 和 JVM 运行时数据区(堆、栈、方法区等)。二者本质不同:
- JMM 是一套并发规则,关注线程怎么安全地读写共享变量
- JVM 内存区域是物理划分,关注程序运行时数据存在哪、怎么分配回收
可以类比为:JVM 内存区域是仓库的物理分区,规定货物(对象、变量)放在哪里;JMM 是工人(线程)取放货物的操作守则,规定怎么避免争抢、误读、漏更新。

















