轉自:http://www.java265.com/JavaCourse/202204/2928.html
下文筆者將講述wait和notify關鍵字的簡介說明,如下所示:
wait()和notify()簡介
void notify()
喚醒在此物件監視器上等待的單個執行緒
void notifyAll()
喚醒在此物件監視器上等待的所有執行緒
void wait( )
導致當前的執行緒等待,直到其他執行緒呼叫此物件的notify( ) 方法或 notifyAll( ) 方法
void wait(long timeout)
導致當前的執行緒等待,直到其他執行緒呼叫此物件的notify() 方法或 notifyAll() 方法,或者指定的時間過完,
void wait(long timeout, int nanos)
導致當前的執行緒等待,直到其他執行緒呼叫此物件的notify( ) 方法或 notifyAll( ) 方法,
或其他執行緒打斷了當前執行緒,或指定的時間過完,
wait(),notify(),notifyAll()都不屬于Thread類
而是屬于Object基礎類
每個物件都有wait(),notify(),notifyAll()的功能
因為每個物件都有鎖,鎖是每個物件的基礎,當然操作鎖的方法也是最基礎了,
當需要呼叫以上的方法的時候,一定要對競爭資源進行加鎖
如果不加鎖的話,則會報 IllegalMonitorStateException 例外
當想要呼叫wait()進行執行緒等待時,必須要取得這個鎖物件的控制權(物件監視器)
一般是放到synchronized(obj)代碼中
在while回圈里而不是if陳述句下使用wait
這樣,會在執行緒暫停恢復后都檢查wait的條件,
并在條件實際上并未改變的情況下處理喚醒通知
呼叫obj.wait( )釋放了obj的鎖
否則其他執行緒也無法獲得obj的鎖,也就無法在synchronized(obj){ obj.notify() } 代碼段內喚醒A
notify()方法只會通知等待佇列中的第一個相關執行緒(不會通知優先級比較高的執行緒)
notifyAll()通知所有等待該競爭資源的執行緒(也不會按照執行緒的優先級來執行)
假設有三個執行緒執行了obj.wait()
那么obj.notifyAll( )則能全部喚醒tread1,thread2,thread3
但是要繼續執行obj.wait()的下一條陳述句
必須獲得obj鎖
因此tread1,thread2,thread3只有一個有機會獲得鎖繼續執行
如tread1,其余的需要等待thread1釋放obj鎖之后才能繼續執行
當呼叫obj.notify/notifyAll后,呼叫執行緒依舊持有obj鎖
因此,thread1,thread2,thread3雖被喚醒
但是仍無法獲得obj鎖,
直到呼叫執行緒退出synchronized塊,釋放obj鎖后
thread1,thread2,thread3中的一個才有機會獲得鎖繼續執行,
public class WaitNotifyTest { //java265.com示例分享在多執行緒間共享的物件上使用wait private String[] shareObj = { "true" }; public static void main(String[] args) { WaitNotifyTest test = new WaitNotifyTest(); ThreadWait threadWait1 = test.new ThreadWait("wait thread1"); threadWait1.setPriority(2); ThreadWait threadWait2 = test.new ThreadWait("wait thread2"); threadWait2.setPriority(3); ThreadWait threadWait3 = test.new ThreadWait("wait thread3"); threadWait3.setPriority(4); ThreadNotify threadNotify = test.new ThreadNotify("notify thread"); threadNotify.start(); threadWait1.start(); threadWait2.start(); threadWait3.start(); } class ThreadWait extends Thread { public ThreadWait(String name){ super(name); } public void run() { synchronized (shareObj) { while ("true".equals(shareObj[0])) { System.out.println("執行緒"+ this.getName() + "開始等待"); long startTime = System.currentTimeMillis(); try { shareObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println("執行緒" + this.getName() + "等待時間為:" + (endTime - startTime)); } } System.out.println("執行緒" + getName() + "等待結束"); } } class ThreadNotify extends Thread { public ThreadNotify(String name){ super(name); } public void run() { try { //讓程式暫停一下 sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (shareObj) { System.out.println("執行緒" + this.getName() + "開始準備通知"); shareObj[0] = "false"; shareObj.notifyAll(); System.out.println("執行緒" + this.getName() + "通知結束"); } System.out.println("執行緒" + this.getName() + "運行結束"); } } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469464.html
標籤:Java
