java執行緒學習(四):執行緒等待wait()和通知notify()的詳細使用
阿新 • • 發佈:2018-12-18
執行緒等待wait()和通知notify(),主要用於多執行緒之間的協作,而且這兩個方法都是屬於Object類,說明任何物件都可以呼叫這兩個方法。
當在一個物件例項上呼叫wait()方法後,當前執行緒就會在這個物件上等待。直到另外的執行緒呼叫了notify()方法,出於等待的執行緒才得以繼續進行。這樣,多執行緒之間的協作就可以用這兩個方法進行通訊了。
先看下例子:
package stop_demo; public class Wait_notify_demo { final static Object object=new Object(); final static Object object2=new Object(); public static class T1 extends Thread{ public void run(){ synchronized (object) { System.out.println(System.currentTimeMillis()+" :T1 啟動!"); try { System.out.println(System.currentTimeMillis()+" :T1等待object鎖。。。。。"); object.wait(); System.out.println("object被喚醒。。。"); } catch (Exception e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()+" T1 end"); } } } public static class T2 extends Thread{ public void run(){ synchronized (object) { System.out.println(System.currentTimeMillis()+" :T2 start! 隨機通知一條執行緒。"); object.notify();//要object例項呼叫notify才行 System.out.println(System.currentTimeMillis()+" T2 end"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { Thread t1=new T1(); Thread t2=new T2(); t1.start(); t2.start(); } }
輸出結果:
可以看到,t1執行緒啟動後,進入等待狀態,t2執行緒執行,當執行object.notify()時,通知等待佇列中的執行緒啟動,也就是t1啟動,然後繼續往下執行。
多執行幾次,就會發現有時候輸出這樣的:
原因是T2先執行,結果t1執行後,執行wait方法而處於一直等待狀態,因為沒有其他執行緒去喚醒t1執行緒。
不過應該注意的是:
-
wait() 和 notify()必須配合synchrozied關鍵字使用,無論是wait()還是notify()都需要首先獲取目標物件的一個監聽器。
-
wait()會釋放鎖,而notify()不釋放鎖。
wait()會釋放鎖,而notify()不釋放鎖,這個是怎麼理解呢?其實看第一個輸出截圖就可以知道,當t1執行到wait方法時,如果t1沒有釋放鎖,那麼t2執行緒壓根就無法執行下去,說明wait()會釋放鎖,而當執行到t2中的notify時,t2會在當前執行緒往下執行,執行完了才讓t1繼續執行,說明notify方法並沒有把鎖釋放了。