2013-04-30 105 views
3

假設我有兩個線程。線程1正在訪問同步方法,同時,線程2正在訪問同一對象的另一個同步方法。正如我所知道的,Thread2應該等到Thread1完成任務。我的問題是,對象的等待線程列表上是否有Thread2?對我來說似乎是這樣,但Thread2不會調用wait()方法,那麼作爲邏輯結果,它不應該在對象的等待線程列表中。如果它不在對象的等待線程列表中,Thread2的狀態是什麼?java同步和對象鎖定

回答

0

這兩種情況之間有區別,因爲您有權正確記錄。

當一個線程嘗試運行​​塊,但一些其他線程持有監視器的鎖,輸入線程是阻塞,直到鎖被釋放,並授予它。

對於一個線程來調用wait(),它必須已經持有顯示器的鎖(這是一個相關的區別)。 此外,調用wait()會使線程等待(釋放鎖定),通常直到它被通過某個其他線程通知

通常上述應總是,在理想的情況下,但是,作爲Java文檔中指定,這種現象稱爲可能發生虛假喚醒,使得等待線程喚醒爲沒有明顯的原因。這就是爲什麼等待條件應該包含在while聲明中,而不是if。例如:

synchronized (this) { 
    while (x < 0) { wait(); } 
} 

代替:

synchronized (this) { 
    if (x < 0) { wait(); } 
} 
2

當Tread2正在等待Thread1釋放Thread1所擁有的固有鎖定時,其將阻止,直到內部鎖定變爲可用(如由執行線程Thread1釋放)。所以,總而言之,Thread2正在等待鎖被釋放,所以它可以獲得它。

現在,當一個線程調用wait(),時,它必須已經擁有固有鎖。撥打wait()然後的呼叫釋放鎖,並使線程處於等待狀態,其中它等待來自notify()notifyAll()的信號繼續執行。

因此,這兩種情況是不同的,前者是關於執行隱式被阻塞,直到資源(鎖)變爲可用。而後者是關於明確釋放一個已經存在的鎖,然後等待一個信號,指出它重新獲得鎖的時間並繼續。