2012-07-13 58 views
3

據說在JLS在支持Java之前發生關係,澄清需要

兩個動作可以由之前發生的關係進行排序。如果一個動作之前發生另一個,則第一個是可見的,並在第二個之前訂購。

也有說:

寫入在一個線程正在一個數據爭與另一個線程讀取可以,例如,顯示爲不按順序發生的那些讀取。

這是否意味着,如果hb(r, w),然後r之前必須w,或如果r是之前,那麼之前發生關係發生?

+0

此鏈接可能會有所幫助:[修復Java內存模型 - 第2部分]的作者Brian Goetz是Oracle的Java語言架構師(https://www.ibm.com/developerworks/library/j-jtp03304/)。 – 2012-07-13 11:24:09

回答

6

hb(r, w)表示rw之前執行且w可以看到r的結果。

在讀的情況下/寫操作,您通常關心有hb(w, r),並希望確保讀看到寫的結果。

實施例使用同步塊:

w(寫入):

synchronized (lock) { //lock is a final object 
    aVariable = something; 
} 

r(讀取):

synchronized (lock) { //the same final object 
    System.out.println(aVariable) 
} 

wr在同一監視器上同步,所以有一個之前發生的2

之間關係

假設wr之前執行,表示我們有hb(w, r),那麼JMM保證r將打印最新值aVariable

沒有同步塊,沒有之前發生任何更多即使wr之前執行(從掛鐘透視)的關係,r可能打印的aVariable陳舊值。

如果沒有之前發生關係,它甚至可能是w是即使你的程序是用一種方式,它不應該是這樣的r之後執行的情況下(即JVM可能重新排序的操作)。

如何怪異的事情可能會變得沒有一個很好的例子之前發生關係是在JLS - Example 17.4-1給出。