主内存和工作内存
在JVM内存模型(JMM)中,主内存和工作内存是两个抽象的内存区域(并非物理内存的实际划分,也不等同于JVM运行时数据区的堆、栈,更不是CPU的物理缓存/寄存器),是JMM为了规范多线程共享变量访问规则而定义的核心概念,所有线程的内存操作均围绕这两个抽象区域的交互展开。
简单来说:主内存是共享变量的“公共仓库”,工作内存是每个线程操作变量的“私人工作台”,线程无法直接操作公共仓库的变量,只能先把变量拿到自己的私人工作台处理,处理完再写回公共仓库。
一、主内存(Main Memory)
核心定义
所有线程共享的全局抽象内存区域,是JMM中共享变量的唯一真实数据源,共享变量的最新值、原始值仅存在于主内存中。
关键特性
- 全局共享:属于所有线程的公共内存,无线程私有属性,所有线程均可通过规范的内存操作访问;
- 存储内容:仅存储共享变量,包括:类的实例变量、静态变量、数组元素(这三类变量是多线程间需要共享的核心数据);
- 操作约束:线程无法直接读、写、修改主内存的共享变量,只能通过JMM定义的8种原子操作(read/load/store/write等)完成与工作内存的交互;
- 物理对应:抽象层面主要对应计算机的物理主存(内存条),也包含部分CPU的多级共享缓存(如L3缓存),是底层物理共享存储的抽象映射。
二、工作内存(Working Memory)
核心定义
每个线程独有的私有抽象内存区域,是线程操作变量的临时缓冲区,线程对共享变量的所有操作(读、改、计算)都必须在自身的工作内存中完成,而非直接操作主内存。
关键特性
- 线程私有:每个线程有且仅有一份独立的工作内存,其他线程无法访问,线程间的工作内存相互隔离;
- 存储内容
- 主内存中共享变量的副本(线程需要操作某个共享变量时,会先从主内存读取最新值,在自身工作内存创建副本);
- 线程的局部变量(方法内的局部变量、方法参数、局部常量):这类变量本身不共享,直接存储在工作内存中,不参与主内存与工作内存的交互,因此局部变量天然是线程安全的;
- 操作核心:线程的执行引擎(计算、判断等)仅能直接访问自身工作内存中的数据,是线程与主内存交互的“中间层”;
- 物理对应:抽象层面主要对应计算机的CPU高速缓存(L1/L2缓存)、寄存器、执行引擎的临时数据区,是底层线程私有存储的抽象映射。
三、主内存与工作内存的核心交互规则(JMM的基础约束)
这是理解二者关系的关键,也是JMM规范的核心,所有多线程内存操作都必须遵循:
- 线程操作共享变量时,必须先将主内存的最新值读取到自身工作内存,创建副本(通过read+load操作),才能进行后续操作;
- 线程修改工作内存中的共享变量副本后,必须通过store+write操作将新值写回主内存,才能让其他线程感知到修改(普通共享变量无强制写回要求,这也是可见性问题的根源);
- 共享变量的真实值仅存在于主内存,工作内存中的副本只是临时快照,多个线程的工作内存中会存在同一个共享变量的多个不同副本;
- 线程间的共享变量值传递,必须通过主内存中转:线程A的修改→写回主内存→线程B从主内存读取最新值,无法直接在两个线程的工作内存之间传递数据。
四、通俗举例(结合之前的实操案例)
以实操中flag布尔共享变量为例:
- 程序启动后,
flag=false首先被初始化在主内存中,这是它的真实值; - 读取线程启动后,通过
read+load操作从主内存读取flag=false,在自身工作内存创建flag的副本; - 主线程修改
flag时,先在自身工作内存修改副本为true,若flag无volatile修饰,主线程不会立即执行store+write写回主内存; - 读取线程始终循环访问自身工作内存中的
flag=false副本,未从主内存重新加载,因此永远感知不到修改,出现可见性问题; - 当
flag被volatile修饰后,主线程修改副本后会强制执行store+write将true刷回主内存,且读取线程会强制失效自身副本,每次循环都从主内存重新加载,从而解决可见性问题。
五、易混淆点区分
1. 工作内存 ≠ JVM运行时数据区的“虚拟机栈/本地方法栈”
- 工作内存是JMM的抽象概念,用于规范多线程内存访问;
- 虚拟机栈是JVM的实际内存区域,用于存储方法的栈帧、局部变量表等,是JVM运行时的物理内存划分之一;
- 二者有映射关系(如虚拟机栈的局部变量表会对应工作内存的局部变量存储),但并非同一概念。
2. 共享变量副本 ≠ 局部变量
- 共享变量副本:是主内存共享变量的临时快照,参与主从内存交互,存在线程安全问题;
- 局部变量:直接存储在工作内存,不共享、不参与主从交互,无线程安全问题。
3. 抽象内存 ≠ 物理内存
JMM的主内存/工作内存是逻辑规范,而非物理上的独立内存块,其底层会映射到物理主存、CPU缓存、寄存器等不同的物理存储介质,JMM通过屏蔽这些底层物理差异,保证Java程序的跨平台并发一致性。

浙公网安备 33010602011771号