jmm是抽象规范,定义多线程下共享变量读写的合法性边界,而非物理内存布局;它聚焦可见性、原子性、有序性三大问题,通过主内存/工作内存模型、happens-before规则及volatile/synchronized等机制保障线程安全。

区分 JMM 和 JVM 运行时数据区
这是所有混淆的起点:JMM 是抽象规范,不是物理内存图。它不定义“堆在哪儿”“栈有多大”,而是定义:一个线程对变量的写,什么时候、以什么方式,对另一个线程可见。
- JVM 运行时数据区(堆、方法区、栈等)——回答“程序运行时,数据存在哪”
- Java 内存模型(JMM)——回答“多线程读写同一个 int 变量,哪些结果合法、哪些被禁止”
- 面试中若答“JMM 就是堆栈方法区划分”,直接扣分
紧扣三大问题配核心内容
JMM 的设计目标非常明确:解决现代硬件带来的并发缺陷。教程必须围绕这三类问题展开,每类配对应机制:
- 可见性:线程 A 改了 flag = true,线程 B 看不到?→ 引出主内存/工作内存模型、volatile 写后刷主存、读前从主存加载
- 有序性:代码顺序是 a=1; b=2;,实际执行可能 b 先于 a?→ 讲指令重排序约束,happens-before 如何禁止关键重排
- 原子性:i++ 不是原子操作 → 说明 JMM 仅保证基本读写原子性,复合操作需 synchronized 或 CAS
用 happens-before 串起全部知识点
这是 JMM 在代码层面的唯一抓手,也是面试必问。教程里要把它作为逻辑主线,而不是罗列规则:
- 程序顺序规则:单线程内,代码上下文决定先后
- 监视器锁规则:unlock happens-before 后续 lock → 解释 synchronized 为什么能保证可见性
- volatile 规则:volatile 写 happens-before 后续任意读 → 对应 volatile 的内存语义,非“立即同步”而是禁止重排+强制刷写
- 传递性:A hb B,B hb C ⇒ A hb C → 用于分析复杂同步链(如 Thread.start() → run() → notify() → wait() 唤醒)
搭配典型代码陷阱讲透原理
光背规则没用,得让学习者一眼识别错误模式。例如:
- 双重检查锁定(DCL)中未用 volatile 修饰单例引用 → 可能导致其他线程看到未初始化完成的对象
- 仅靠 synchronized 修饰 setter,但 getter 没加锁 → 修改可见,但读取可能仍读到旧值(因无 happens-before 链)
- final 字段构造器内赋值 → JMM 保证构造完成时,该字段值对其他线程可见(安全发布),但普通字段不享受此保障
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











