Java 內存模型(JMM)定義了線程與主內存之間的交互規範,是並發編程正確性的基石。本文系統總結 JMM 核心概念、volatile 語義、三大特性(原子性、可見性、有序性)、happens-before 原則及指令重排。
現代 CPU 多核架構下,各核心擁有私有高速緩存,導致緩存一致性問題。JMM 屏蔽硬體/OS 差異,規範 JVM 變量在主內存與線程工作內存間的讀寫協議,保證跨平台並發行為一致。


read、load、use、assign、store、write、lock、unlock。單個操作原子,但操作序列可被打斷。
volatile 變量立即刷新至主內存,讀取時強制從主內存加載,其他線程立即可見。// 線程 A
boolean stop = false;
while (!stop) { doSomething(); }
// 線程 B
stop = true; // 未加 volatile,A 可能永遠看不到更新

加上 volatile 後,B 寫入強制刷主存並使 A 工作內存緩存行失效,A 重讀獲取最新值,循環正常終止。
i++ 非原子,不可用 volatile)。典型適用:boolean 狀態標誌、單獨的 long/double 讀寫(JDK 5+ 保證 64 位原子)。
| 特性 | 定義 | 實現手段 |
|---|---|---|
| 原子性 | 操作不可分割,要麼全做要麼全不做 | synchronized、Lock、基本類型讀寫(除 64 位非 volatile) |
| 可見性 | 一線程修改,他線程立即可見 | volatile、synchronized(unlock 前刷主存)、final(初始化後可見) |
| 有序性 | 本線程內有序,跨線程可能無序 | volatile(禁止重排)、synchronized(鎖串行化)、happens-before 規則 |
編譯器/處理器為優化性能會重排無數據依賴的指令。JMM 通過 happens-before 規則約束重排:
// 線程 A
a = 1; flag = true;
// 線程 B
if (flag) { int i = a + 1; } // 可能讀到 a=0,因為 A 可能重排為 flag=true; a=1;

解決:將 flag 聲明為 volatile,或雙方加同步鎖(利用鎖定規則)。
C/C++ 早期標準無內建線程模型,依賴 pthreads 等庫與編譯器/硬體保障。C++11 才引入標準內存模型(std::atomic、memory_order),與 JMM 理念相近但更底層靈活。