2015-12-30 103 views
3

據我所知,Visibility可以處理線程觀察/查看另一個線程更新共享變量的條件。 即使是單處理器系統也可能遭受可見性問題。 Ordering處理線程看到另一個CPU中另一次運行所執行的內存操作的順序。 單處理器系統不會遭受訂購問題。 但是,我覺得有時所謂的Ordering問題可以用可見性的概念來解釋,例如,g。可見性和排序之間的關係/區別是什麼?

//Thread1 runs 
int data; 
boolean ready; 
void method1(){ 
    data=1; 
    ready=true; 
} 

//Thread2 runs 
void method2(){ 
    if(ready){ 
    System.out.print(data); 
    } 
} 

如果上述程序的輸出爲「0」(而不是「1」),我們可以說,有一個排序的問題(即重新排序)---在寫準備出現在寫入數據之前發生。然而,我認爲我們也可以將這個輸出解釋爲可見性的結果:Thread2首先看到更新到已準備好 by Thread1,然後數據,可能是因爲Store Buffer刷新到CPU Cache,並且如果打印數據)在Thread2看到更新爲數據之前執行,然後我們得到輸出「0」。 考慮到這一點,我只是想知道可見性和排序之間的區別/關係是什麼?

+0

看看Doug Lea關於[同步和Java內存模型](http://gee.cs.oswego.edu/dl/cpj/jmm.html)的這篇文章。這是關於原子性,可見性和各種排序的一個很好的概述,可能會與您期望的不同。這是來自同一作者的另一篇關於[JSR-133 - Java內存模型](http://gee.cs.oswego.edu/dl/jmm/cookbook.html)的文章。 – SubOptimal

+0

我想補充一個(因爲我只是偶然發現)http://jpbempel.blogspot.fr/2013/05/volatile-and-memory-barriers.html – SubOptimal

+0

謝謝@SubOptimal,你的建議文章很好,在我問這個問題之前,我已經閱讀過它們。 – user2351818

回答

1

是的,訂購和可視性是相關的問題。

  • 能見度是否/何時一個線程看到的存儲器中的結果寫入由另一個線程

  • 訂貨是關於其中更新由第二線程看到的順序是否匹配(程序)進行第一個線程寫入它們的順序。

Java內存模型不直接解決寫入順序。訂單的任何約束(正如你所假設的那樣)是可見性規則的結果:這些都是在JLS中指定的。這包括您使用volatile變量有效抑制重新排序的情況。

還值得注意的是,只要JLS內存模型不需要可見性,就可以重新排序寫入(從第二個線程的角度來看)。正確的同步將保證同步點的可視性。

相關問題