2012-04-16 105 views
4

可能重複:
Does thread.yield() lose the lock on object if called inside a synchronized method?Yield/Join釋放監視器鎖定?

我知道Thread.sleep()持有鎖,但Object.wait()釋放鎖。有人說yield實際上實現了sleep(0)。這是否意味着收益率不會釋放鎖?

另一個問題。假設當前線程已獲得鎖定,然後調用anotherThread.join()。當前線程是否釋放鎖定?

+1

Java [docs] [1]說:*每個對象都有一個與之相關的固有鎖。按照慣例,需要對對象字段進行獨佔且一致訪問的線程在訪問它們之前必須先獲取對象的內部鎖,然後在完成對象的內部鎖時釋放內部鎖。* 所以我覺得,由於鎖屬於一個對象,'Thread'類的靜態方法不應該控制這些鎖。這就是爲什麼只有'Object'類'wait()'方法。我不確定,但這是我的感受。 [1]:http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html – 2012-04-16 14:38:28

+0

儘管yield()與sleep(0)類似,但您可以發現sleep(0)長100倍,所以它們不完全相同。只有在鎖定的對象上等待()纔會釋放鎖。 – 2012-04-16 15:40:23

回答

3

除非javadoc提到對象的監視器(例如Object.wait()),否則應該假定任何鎖都將繼續保留。所以:

這是否意味着收益率不會釋放鎖?

是的。

當前線程是否釋放鎖?

1

sleep使線程處於等待狀態,yield直接返回線程就緒池。 (所以如果一個線程產生的話,它可以直接從運行到準備池,再次被調度器選中而不需要等待)。兩者都沒有任何關係。

Java Language Specification

的Thread.sleep使得當前執行的線程休眠 (暫停執行)用於指定的持續時間,但須 精度和系統計時器和調度程序的準確性。線程 不會丟失任何監視器的所有權,並且恢復執行 將取決於調度和執行線程的處理器的可用性。

請務必注意,Thread.sleep和Thread.yield 都沒有任何同步語義。特別是,在調用Thread.sleep或Thread.yield之前,編譯器不需要將緩存在寄存器中的寫入緩存到共享內存 ,編譯器 也不必在調用線程之後重新加載緩存在寄存器中的值。睡眠 或Thread.yield。

例如,在下面的(虛線)的代碼段中,假定 this.done是非易失性布爾字段:

while (!this.done) 
    Thread.sleep(1000); 

編譯器可以自由地讀出的場this.done只有一次,並在循環的每次執行中重新使用緩存的值。這意味着即使另一個線程更改了this.done的值 ,該循環也不會終止。