3
兩個動作可以由之前發生的關係進行排序。如果一個動作之前發生另一個,則第一個是可見的,並在第二個之前訂購。
也有說:
寫入在一個線程正在一個數據爭與另一個線程讀取可以,例如,顯示爲不按順序發生的那些讀取。
這是否意味着,如果hb(r, w)
,然後r
之前必須w
,或如果r
是之前,那麼之前發生關係發生?
兩個動作可以由之前發生的關係進行排序。如果一個動作之前發生另一個,則第一個是可見的,並在第二個之前訂購。
也有說:
寫入在一個線程正在一個數據爭與另一個線程讀取可以,例如,顯示爲不按順序發生的那些讀取。
這是否意味着,如果hb(r, w)
,然後r
之前必須w
,或如果r
是之前,那麼之前發生關係發生?
hb(r, w)
表示r
在w
之前執行且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)
}
w
和r
在同一監視器上同步,所以有一個之前發生的2
假設w
在r
之前執行,表示我們有hb(w, r)
,那麼JMM保證r
將打印最新值aVariable
。
沒有同步塊,沒有之前發生任何更多即使w
被r
之前執行(從掛鐘透視)的關係,r
可能打印的aVariable
陳舊值。
如果沒有之前發生關係,它甚至可能是w
是即使你的程序是用一種方式,它不應該是這樣的r
之後執行的情況下(即JVM可能重新排序的操作)。
如何怪異的事情可能會變得沒有一個很好的例子之前發生關係是在JLS - Example 17.4-1給出。
此鏈接可能會有所幫助:[修復Java內存模型 - 第2部分]的作者Brian Goetz是Oracle的Java語言架構師(https://www.ibm.com/developerworks/library/j-jtp03304/)。 – 2012-07-13 11:24:09