04.Java内存模型JMM
总结
- JMM 核心:提供按需禁用缓存与编译优化的方法(volatile/synchronized/final + happens-before)
- volatile 保证可见性和有序性,不保证原子性
- happens-before 六条规则约束编译器优化,Lock 的可见性也依赖这套规则
JMM 的核心目标:提供按需禁用缓存与编译优化的方法,即 volatile、synchronized、final 以及 happens-before 规则。
1. volatile
禁用 CPU 缓存,对 volatile 变量的读写直接操作主内存,保证可见性与有序性,但不保证原子性。底层原理见 Volatile关键字的底层原理。
2. final
告诉编译器"这个变量生而不变",可以大胆优化。正确使用 final 可以避免对象逸出问题。
3. happens-before 六条规则
前一个操作的结果对后续操作可见,约束编译器优化不能违反这些规则。Lock 的可见性也依赖这套规则(内部 volatile state + 传递性)。
| 规则 | 说明 |
|---|---|
| 程序顺序性 | 同一线程内,前面的操作 Hb 后面的操作 |
| volatile 规则 | 对 volatile 变量的写 Hb 后续对该变量的读 |
| 传递性 | A Hb B,B Hb C → A Hb C |
| 管程锁规则 | 解锁 Hb 后续加锁(synchronized 的可见性保障来源) |
| 线程 start 规则 | 主线程调用 B.start() 前的操作,B 线程都能看到 |
| 线程 join 规则 | B.join() 返回后,B 线程的所有操作主线程都能看到 |