深入解析Java内存模型:JMM核心机制
好的,我们来深入探讨Java内存模型(JMM)的核心机制,重点关注内存屏障、重排序和Happens-Before规则。这些是理解并发编程中可见性和有序性的关键。
一、内存屏障(Memory Barrier)
内存屏障是处理器或编译器提供的特殊指令,用于控制内存操作的执行顺序和可见性。JMM定义了四种基本类型:
-
LoadLoad屏障
确保屏障前的读操作(Load)先于屏障后的读操作完成。Load A; LoadLoad; Load B; // 保证A的读取在B之前完成 -
StoreStore屏障
确保屏障前的写操作(Store)先于屏障后的写操作对其他处理器可见。Store A; StoreStore; Store B; // 保证A的写入在B写入前对其他处理器可见http://my.tv.sohu.com/us/441548290/698949778.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTc3OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949864.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTg2NC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950038.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDAzOC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950111.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDExMS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949980.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk4MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950133.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDEzMy5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949989.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk4OS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949993.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk5My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950182.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDE4Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950341.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM0MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950350.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM1MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950263.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDI2My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950410.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQxMC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950505.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDUwNS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950372.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM3Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950374.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM3NC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950441.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ0MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950448.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ0OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950453.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ1My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950702.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDcwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950546.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDU0Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950558.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDU1OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950802.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950753.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc1My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950663.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDY2My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950818.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgxOC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950671.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDY3MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950834.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgzNC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950790.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc5MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950793.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc5My5zaHRtbA==.html
-
LoadStore屏障
确保屏障前的读操作先于屏障后的写操作完成。Load A; LoadStore; Store B; // 保证A的读取在B写入前完成 -
StoreLoad屏障
最严格的屏障,确保屏障前的写操作对其他处理器可见,且屏障后的读操作能读到最新值。Store A; StoreLoad; // 刷新写缓冲区,保证A的写入全局可见 Load B; // 能读到其他处理器写入的最新值
二、重排序(Reordering)
编译器和处理器为了优化性能,可能对指令进行重排序。JMM通过禁止特定重排序来保证正确性:
| 操作类型 | 是否允许重排序 | 示例场景 |
|---|---|---|
| 普通读-普通写 | 允许 | int a = x; int b = y; |
| volatile读-写 | 禁止 | volatile int v; |
| final字段操作 | 禁止与其他操作重排序 | final int f; |
三、Happens-Before规则
Happens-Before定义了操作间的偏序关系,保证前一个操作的结果对后一个操作可见:
- 程序顺序规则
同一线程内,书写在前面的操作Happens-Before后面的操作。 - volatile规则
volatile变量的写操作Happens-Before后续对该变量的读操作。 - 锁规则
解锁操作Happens-Before后续的加锁操作。 - 线程启动规则
Thread.start()Happens-Before新线程的所有操作。 - 线程终止规则
线程中的所有操作Happens-BeforeThread.join()的返回。 - 传递性规则
若A Happens-Before B,且B Happens-Before C,则A Happens-Before C。
四、示例:volatile的可见性
public class VolatileExample {
private volatile boolean flag = false;
public void writer() {
flag = true; // volatile写
}
public void reader() {
if (flag) { // volatile读
System.out.println("Flag is true");
}
}
}
http://my.tv.sohu.com/us/441548290/698949778.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTc3OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949864.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTg2NC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950038.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDAzOC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950111.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDExMS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949980.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk4MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950133.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDEzMy5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949989.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk4OS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698949993.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk0OTk5My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950182.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDE4Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950341.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM0MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950350.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM1MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950263.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDI2My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950410.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQxMC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950505.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDUwNS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950372.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM3Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950374.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDM3NC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950441.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ0MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950448.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ0OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950453.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDQ1My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950702.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDcwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950546.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDU0Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950558.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDU1OC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950802.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950753.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc1My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950663.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDY2My5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950818.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgxOC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950671.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDY3MS5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950834.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDgzNC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950790.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc5MC5zaHRtbA==.html
http://my.tv.sohu.com/us/441548290/698950793.shtml
https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5ODk1MDc5My5zaHRtbA==.html
- Happens-Before链:
writer()中的写操作Happens-Beforereader()中的读操作,保证flag的修改对读线程可见。
五、final字段的特殊性
final字段在构造函数中初始化后,其值对其他线程立即可见,无需同步:
public class FinalExample {
private final int x;
public FinalExample(int val) {
x = val; // 构造函数内初始化
}
public int getX() {
return x; // 其他线程直接读到正确值
}
}
- JMM保证:
构造函数中对final字段的写入Happens-Before任何其他线程读取该字段。
总结
Java内存模型通过内存屏障、重排序约束和Happens-Before规则,为开发者提供了可预测的并发语义。理解这些机制,是编写正确、高效并发程序的基础。









