2012-01-25 108 views
5

我只是有一個問題關於同時運行的線程和鎖對象。據我所知,調用wait()方法的線程將進入等待列表,並允許阻塞列表中的另一個線程接管鎖和對象(在同步代碼中)。 如果此線程現在具有對象的鎖定,則會調用notify()方法,喚醒調用wait()的線程並將其移至阻止列表。瞭解多線程

調用notify()方法的線程會發生什麼情況。它是否仍然鎖定對象,或者現在是否在等待列表中?

關於

回答

5

只有一個線程可以容納一個對象的鎖。當線程持有你調用這些方法的對象的鎖時,必須調用wait()notify()方法;如果他們不(例如,因爲你沒有在對象上同步),你會得到一個IllegalMonitorStateException

當您調用wait()時,線程放棄鎖定並等待列表(停止執行)。當wait()返回時,線程將再次獲得鎖定。但是,調用notify()的線程仍然保持鎖定狀態,因此等待的線程在通知線程退出​​塊或方法之前不會恢復,以便它釋放對象的鎖定。

通過調用notify()線程不放棄鎖定對象。

事件的可能的順序是:

  • 線程1進入一個​​塊,從而獲得鎖定的對象
  • 線程在對象上1個通話wait(),放棄鎖,停止執行
  • 線程2進入一個​​塊,獲得鎖的對象的對象
  • 線程2調用notify(),但仍持有鎖
  • 線程1被喚醒並嘗試獲得鎖,但它不能因爲線程2仍然有它(這樣線程1必須等待鎖)
  • 線程2退出​​塊和釋放鎖
  • 線程1現在可以獲得鎖並從wait()返回
4

通知線程仍然擁有鎖定。請參見doc第17.14節(頁面底部):

只有噹噹前線程已鎖定對象的鎖定時,才應該爲對象調用notify方法。如果等待設置的對象不是空的,則某些任意選擇的線程將從等待集中移除並重新啓用以進行線程調度。 (當然,直到當前線程放棄對象的鎖定,該線程才能繼續)。

1

不,它將通過保留同步塊或從同步方法返回來釋放鎖。在再次撥打wait()之前,它不會返回到等待列表。