當多線程程序未正確同步時,會產生資料競爭。JMM 規範定義資料競爭需同時滿足三個條件:
存在資料競爭的程序執行結果往往違反直覺。JMM 承諾:若程序正確同步(廣義同步,含 lock、volatile、final),其執行將具備順序一致性——即執行結果與順序一致性記憶體模型中的結果相同。
SC 是電腦科學家理想化的理論參考模型,提供極強的記憶體可見性保證,具備兩大核心特性:

概念上,SC 擁有單一全局記憶體,透過「開關」串行化所有線程的讀寫操作。任意時刻僅有一線程連接記憶體,確保操作原子性與全局可見性。
線程 A 執行完釋放鎖 → 線程 B 獲取同一鎖。SC 模型中操作完全按程序順序串行執行:

整體執行順序無序,但所有線程看到的操作順序一致。例如線程 A(B1→A1→A2→B2→A3→B3) 與線程 B 看到的順序完全相同,因為每個操作立即對所有線程可見。

在 JMM 中,非同步程序不僅整體無序,不同線程看到的操作順序可能不一致。原因在於:線程將寫入緩存在本地記憶體,未刷新到主記憶體前,該寫入僅對當前線程可見;其他線程會認為寫入根本未發生。只有刷新到主記憶體後,其他線程才能看見。
以 SynchronizedExample 為例:
class SynchronizedExample {
int a = 0;
boolean flag = false;
public synchronized void writer() {
a = 1;
flag = true;
}
public synchronized void reader() {
if (flag) {
int i = a;
// ...
}
}
}
假設線程 A 執行 writer(),線程 B 執行 reader()。JMM 保證執行結果與 SC 模型一致。關鍵在於:

這體現了 JMM 核心設計哲學:在不改變正確同步程序執行結果的前提下,盡可能為編譯器與處理器優化留出空間。
JMM 對非同步程序僅提供最小安全性:線程讀取到的值,要麼是先前某線程寫入的值,要麼是默認值(0、null、false),絕不會憑空產生值。為實現此保證,JVM 在堆上分配對象前會先清零記憶體空間。
現代處理器透過總線事務(讀事務/寫事務)在處理器與記憶體間傳輸數據。總線仲裁確保同一時刻僅一處理器訪問記憶體,保證單個總線事務內的讀寫原子性。

為照顧 32 位處理器,Java 規範鼓勵但不強制 JVM 保證 64 位 long/double 寫入原子性。若 JVM 選擇拆分寫入,兩個 32 位寫操作可能分配到不同總線事務,導致寫入非原子。

如圖:處理器 A 寫 long 變量被拆分為兩個 32 位寫事務,處理器 B 讀取分配到單個讀事務。若時序交錯,B 將讀到「僅寫了一半」的無效值。
自 JDK 5 (JSR-133) 起:
這顯著降低了非原子讀寫導致的數據破壞風險。