1. 程式人生 > 實用技巧 >(二)執行緒通知與等待

(二)執行緒通知與等待

Java併發程式設計之美->讀書筆記

java中的Object類是所有類的父類,鑑於繼承機制,java把所有類都需要的方法放到了Object類裡面,其中就包含本節要將的通知與等待系列函式

1,wait()函式

當一個執行緒呼叫一個共享變數的wait()方法時,該呼叫執行緒會被阻塞掛起,直到發生下面幾件事情之一才返回:
(1)其他執行緒呼叫了該共享物件的notify或者notifyAll()方法;
(2)其他執行緒呼叫了該執行緒的interrupt()方法,該執行緒丟擲InterruptedException異常返回。
另外需要注意的是,如果呼叫wait()方法的執行緒沒有事先獲取該物件的監視器鎖,則呼叫wait()方法時呼叫執行緒會丟擲IllegalMonitorStateException異常。

那麼一個執行緒如何才能獲取一個共享變數的監視器鎖呢?
(1)執行synchronized同步程式碼塊時,使用該共享變數作為引數
synchronized(共享變數){
   //doSomething
}
(2)呼叫該共享變數的方法,並且該方法使用了synchronized修飾.
synchronized void add(int a,int b){
    //doSomething
}
另外需要注意的是,一個執行緒可以從掛起狀態變為可以執行狀態(也就是被喚醒),
即使該執行緒沒有被其他執行緒呼叫notify()、notifyAll()方法進行通知,或者被中斷,或者等待超時,這就是所謂的虛假喚醒。
雖然虛假喚醒在應用實踐中很少發生,但要防患於未然,做法就是不停的去測試該執行緒被喚醒的條件是否滿足,
不滿足則繼續等待,也就是說在一個迴圈中呼叫wait()方法進行防範。退出迴圈的條件是滿足了喚醒該執行緒的條件。
synchronized (obj) {
  while (條件不滿足) {
  obj.wait();
      }
 }