數據依賴類型(重排會改變結果):
編譯器/處理器遵守單線程/單處理器內數據依賴,不重排存在依賴的操作。跨線程/處理器依賴不被考慮。
無論如何重排序,單線程程序執行結果不能改變。編譯器、runtime、處理器共同遵守,為單線程程序員創造「按程序順序執行」的幻覺。
double pi = 3.14; // A
double r = 1.0; // B
double area = pi * r * r; // C
依賴關係:A→C、B→C。A、B 無依賴可重排。
兩種合法執行順序:
示例存在 3 個 hb:A→B、B→C、A→C(傳遞性)。
關鍵認知:A hb B 不要求 A 必須在 B 前執行,僅要求:
重排 A、B 不改變結果且 A 結果無需對 B 可見 → JMM 允許。體現「不改變結果前提下最大化並行度」共同目標。
class ReorderExample {
int a = 0; boolean flag = false;
void writer() { a = 1; flag = true; } // 1→2
void reader() { if (flag) { int i = a*a; } } // 3→4
}

線程 A 先寫 flag=true,線程 B 讀到 flag 進入判斷,但 a 尚未寫入 → 讀到錯誤值 0。**多線程語義被破壞!**

關鍵差異:單線程中控制依賴重排不改變結果(as-if-serial 允許);多線程中可能改變程序語義!