[英]Is volatile read happens-before volatile write?
我試着理解為什么這個例子是一個正確同步的程序:
a - volatile
Thread1:
x=a
Thread2:
a=5
因為存在沖突的訪問(存在對a的寫入和讀取)所以在每個順序一致性執行中必須發生 - 在該訪問之間的關系之前。 假設一個順序執行:
1. x=a
2. a=5
1發生在2之前,為什么?
1發生在2之前,為什么?
我不是100%確定我理解你的問題。
如果你有一個volatile變量a
,一個線程正在從中讀取而另一個線程正在寫入它,那么這些訪問的順序可以是任意順序。 這是一場競爭 。 JVM和Java內存模型(JMM)保證的內容取決於首先發生的操作。
寫入可能剛剛發生,讀取看到更新的值。 或者寫入可能在讀取后發生。 因此, x
可以是任何5
或以前的值a
。
每個順序一致性執行必須在該訪問之間的關系之前發生
我不確定這意味着什么所以我會嘗試具體。 與volatile
發生“在關系之前發生”意味着在讀取相同變量之前所有先前的內存寫入volatile
變量都保證已完成。 但這種保證絕不能解釋兩種易受競爭條件影響的volatile
運營之間的時間安排。 讀者可以保證已經看到了寫,但只有當讀前寫發生。
您可能認為這是一個非常弱的保證,但在線程中,通過使用本地CPU緩存可以顯着提高其性能,讀取字段的值可能來自緩存的內存段而不是中央內存。 保證對於確保在發生volatile
讀取時本地線程內存無效和更新至關重要,以便線程可以適當地共享數據。
同樣,JVM和JMM保證如果您從volatile
字段a
讀取,那么在讀取之前發生的對同一字段的任何寫入都將被它看到 - 寫入的值將被正確發布並且可見閱讀線程。 但是,這種保證決不會決定訂購。 它並沒有說在寫入之前必須發生寫入。
不,在易失性寫入之前,(同步順序)之前的易失性讀取不一定發生相同變量的易失性寫入。
這意味着他們可以處於“數據競爭”中,因為它們是“沖突的訪問,而不是由先發生過的關系命令”。 如果這是真的,幾乎所有程序都包含數據競爭:)但它可能是一個規范錯誤。 永遠不應將易失性讀寫視為數據競爭。 如果程序中的所有變量都是易失性的,則所有執行都是順序一致的。 見http://cs.oswego.edu/pipermail/concurrency-interest/2012-January/008927.html
抱歉,您無法正確說出JVM如何根據JVM的“內存模型”優化代碼。 您必須使用Java的高級工具來定義您想要的內容。
所以volatile只意味着沒有用於變量的“線程間緩存”。
如果您想要更嚴格的訂單,則必須使用同步塊。
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
易失性和發生之前僅在讀取字段驅動某些條件時才有用。 例如:
volatile int a;
int b =0;
Thread-1:
b = 5;
a = 10;
Thread-2
c = b + a;
在這種情況下,沒有發生 - 之前,a可以是10或0,b可以是5或0,因此結果c可以是0,5,10或15.如果讀取a意味着其他一些條件然后發生before-before例如:
int b = 0;
volatile int a = 0;
Thread-1:
b = 5
a = 10;
Thread 2:
if(a == 10){
c = b + a;
}
在這種情況下,您將確保C = 15,因為讀a==10
暗示的寫b = 5
的之前發生的寫a = 10
編輯:更新添加順序,如灰色所示的不一致
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.