JLS 指出:
一組同步邊S是足夠的,如果它是最小集,使得 S 的傳遞閉包與程式順序決定了執行中的所有先發生邊。這一套是獨一無二的。
為什么充分集是唯一的?
我們如何確定哪些同步邊在充分集中,哪些不在?
uj5u.com熱心網友回復:
這是對您在評論中提出的實際問題的回答:
I don't care. I asked the question because I'm curious about possible optimizations: "the minimal set" means some synchronizes-with edges are not used and thus can be optimized-out.
我試圖對這個話題有一個很好的理解,所以我提供的答案也是為了讓我整理我的想法。
JMM 是抽象機器的規范。它定義了所有可能的合法執行,并且每次執行都有一些結果。如果每次讀取看到的寫入要么是在發生前的順序中最近的寫入,要么是與資料競爭的寫入(為了簡單起見,我們忽略因果關系),則執行是合法的。
JVM 實作沒有義務發出所有可能的合法執行。對于每個發出的執行,只重要的是該執行的結果與 JMM 允許的不同執行沒有區別。
所以換句話說,只要執行的結果是正確的,沒有人關心結果是如何建立的。
讓我們看一個具體的例子:
volatile int a=0
thread1:
a =1
a =1
thread2:
r1=a
所有可能的合法結果都是 r1={0,1,2}。一個有效的 JVM 實作可以優化如下:
volatile int a=0
thread1:
a =2
thread2:
r1=a
這是有效的,因為結果是 r1={0,2},它是合法結果的子集。
之前發生的順序(包括同步順序)僅用于確定可能的法律結果,因此您不需要優化它們中的任何一個。
JVM 實作沒有義務保留原始同步操作,因此在性能優化方面有很大的自由度。
如需更好的解釋,請查看Aleksey Shipilev的精彩演示
uj5u.com熱心網友回復:
我找到了答案。
為什么充分集是唯一的?
根據JLS happens-before是嚴格的偏序:
發生前的順序由 synchronizes-with 邊和程式順序的傳遞閉包給出。它必須是有效的偏序:自反、傳遞和反對稱。
這意味著happens-before 可以表示為有向無環圖(DAG):
嚴格的偏序直接對應于有向無環圖 (DAG)
根據維基:
DAG 的傳遞約簡是與 DAG 具有相同可達性關系的邊最少的圖。DAG的可達關系≤覆寫關系中的
u → v每一對頂點都有一條邊。(u, v)它是 DAG 的子圖,通過丟棄u → vDAG 還包含從u到的更長有向路徑的邊而形成v。與傳遞閉包一樣,傳遞約簡是為 DAG 唯一定義的。
這種“傳遞減少”是問題中的“充分最小集”。
我們如何確定哪些同步邊在充分集中,哪些不在?
從維基:
它是 DAG 的子圖,通過丟棄
u → vDAG 還包含從u到的更長有向路徑的邊而形成v。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/530254.html
上一篇:有沒有辦法將.NETDI中的生命周期限定為執行緒,包括子執行緒?
下一篇:在腳本中實作多執行緒/并行處理
