簡體   English   中英

易失性讀取是否發生在易失性寫入之前?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM