2014-09-04 100 views
4

易失性寫入是否使用非易失性寫入進行重新排序?
對於防爆:
我有兩個線程T1和T2:易失性寫入非易失性寫入重新排序

T1:

i = 10; 
volatile boolean result = true; 

T2:

while(!result){ 
} 

System.out.println(i); 

確實T2總是看到我的更新值(10)還是舊值?

+0

在java中,你不能這樣做'可變int布爾結果=真;'。 – BackSlash 2014-09-04 06:50:39

+0

JLS的相關部分是[17.4.2](http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.2),其中volatile寫法和讀取被列爲同步操作。所以,必須打印10份。 – kiheru 2014-09-04 07:00:47

回答

2

是的。還有就是之前發生的揮發性聲明關係:

請考慮這個計算器的問題:Does Java volatile variables impose a happens-before relationship before it is read?

到揮發性現場寫之前發生以後每的 同場的讀取。寫入和讀取易失性字段與輸入和退出顯示器具有相似的內存一致性效果,但不要求 不需要互斥鎖定。

另外,您還可以在名爲「Java併發實踐」的偉大着作中閱讀第3.1.3節(鎖定和可見性)。這裏有一個關於相似的可見性問題的相關解釋,大綱是這樣的:

鎖定不僅僅是互斥;它也是關於內存visibility.To確保所有線程看到最先進的共享可變變量的日期值,讀取和寫入線程必須在一個共同的鎖

在你的代碼同步鎖是volatile變量

1

據我所知,這是正確的同步,所以沒有比賽發生和10總是打印。

重要的部分是,在一個線程中,事件按程序順序發生,並且寫入一個易失變量發生在看到該值的讀取之前。與傳遞閉包規則一起,這意味着對我的分配發生在打印語句之前。

i = 10發生在result = true之前。 result = true發生在線程2中的result被讀爲true。result被讀作爲真正發生在System.out.println(i);之前。因此,i = 10發生在System.out.println(i);之前。