2010-03-19 55 views
7

Java 6 API問題。是否LockSupport.unpark(thread)有一個發生在之間的關係從LockSupport.park返回在剛剛unparked線程?我強烈懷疑答案是肯定的,但Javadoc似乎沒有明確提及它。Java LockSupport內存一致性

回答

1

我已經查看了JDK代碼,它看起來像LockSupport方法通常在同步塊之外調用。所以,你的假設似乎是正確的。

+1

很抱歉對這樣一箇舊的答案發表評論,但是由於問題是關於Java * API *而不是Sun/Oracle提供的*實現*,所以查看JDK如何使用'LockSupport'並不是100%正確的。 JDK開發人員可能會對其自己的實現做出假設,而便攜式應用程序則不應該這樣做。另外,還有一些方法可以實現* happen-before *關係,而不涉及任何'synchronized'塊。 – rolve 2013-12-02 13:28:39

+0

「......通過JDK代碼查看」:您是否可以爲OpenJDK發佈一個hg URL? – kevinarpe 2015-12-17 08:29:58

5

如果它沒有記錄成這樣,那麼你不能依靠它創建關係之前發生的事情。

特別是Hotspot代碼中的LockSupport.java只需調用Unsafe.park和.unpark!

發生在之間的關係通常來自易失性狀態標誌或類似物上的寫讀取對。

請記住,如果沒有記錄爲創建之前發生關係,那麼你必須把它當作雖然它不能使用,即使你能證明它特定的系統上。未來的系統和實現可能不會。他們有充分的理由讓自己離開了自由。

6

我剛剛發現這個問題,因爲我問自己同樣的事情。根據Oracle研究人員David Dicethis article,答案似乎是沒有。下面是文章的相關部分:

如果一個線程被阻塞在park()我們保證後續 unpark()將使它準備。 park()unpark()的執行完全合法但是質量較差 將是空方法,其中 程序退化爲簡單旋轉。 其實這就是 石蕊試驗正確park() - unpark()的用法。

park()unpark()方法不給你任何之前發生關係的保證,所以對於你的程序是100%可移植的,你不應該依賴他們。

話又說回來,Javadoc of LockSupport說:

這些方法被設計用來作爲工具,用於創建 更高級別的同步實用程序,而不是本身對於大多數併發控制應用 有用。該park方法 只在形式的結構設計用於:

while (!canProceed()) { ... LockSupport.park(this); }

既然你反正明確檢查一些條件,這將既涉及volatile或適當地同步變量,弱擔保park()實際上不應該是問題,對吧?

+2

感謝您的回答。我現在不記得爲什麼我想知道這一點。我懷疑我是在想,當正在運行的線程更新條件並調用'unpark'時,如果它本身能夠保證未停放的線程能夠看到更新後的狀態處於一致狀態。看起來沒有保證,所以唯一安全的選擇是爲條件更新明確安排記憶障礙。 – Lachlan 2013-11-30 12:03:02

+0

我明白了。如果'park()'和'unpark()'之間存在一個*發生之前*關係,那麼這個條件就不需要涉及內存屏障。所以這個問題仍然有效。 – rolve 2013-12-02 13:24:26