外观
一句话答案
JMM 定义多线程环境下变量的可见性和有序性规则,happens-before 是核心语义,共 8 条规则保证内存操作的偏序关系。
核心要点
JMM 核心问题:
- CPU 缓存导致可见性问题
- 编译器/CPU 指令重排导致有序性问题
- 非原子操作导致原子性问题
happens-before 规则(8 条):
- 程序顺序:同一线程中前面的操作 hb 后面的
- 监视器锁:unlock hb 后续对同一锁的 lock
- volatile:写 hb 后续对同一变量的读
- 线程启动:Thread.start() hb 该线程的所有操作
- 线程终止:线程所有操作 hb 其他线程检测到它终止
- 线程中断:interrupt() hb 被中断线程检测到中断
- 对象终结:构造函数完成 hb finalize()
- 传递性:A hb B, B hb C → A hb C
内存屏障实现:
- LoadLoad / StoreStore / LoadStore / StoreLoad
- volatile 写 = StoreStore + StoreLoad
- volatile 读 = LoadLoad + LoadStore
追问与易错
追问方向:
- happens-before 和时间先后有什么关系?
- volatile 写-读的 happens-before 怎么理解?
- DCL 和 happens-before 的关系?
易错点:
- ❌ happens-before 就是时间上先发生——是内存可见性保证
- ❌ 不理解传递性 A hb B, B hb C 则 A hb C
💡 记忆锚点
happens-before不是"时间上先发生",而是"前一个操作的结果对后一个可见"。八条规则记关键四条:程序顺序、锁(unlock先于lock)、volatile(写先于读)、传递性。内存屏障是底层执行者,volatile写后插StoreLoad屏障确保刷到主存。