等待/通知機制
等待/通知機制在生活中比比皆是,舉一個例子,廚師與服務員的例子,他們之間的交互在“菜品傳遞臺”。
1、廚師做完一道菜的時間不確定,所以廚師將菜品放到“菜品傳遞臺”上的時間也不確定。
2、服務員取到菜的時間取決於廚師,所以服務員就有“等待(wait)”的狀態。
3、服務員如何能取到菜?取決於廚師,廚師將菜放在“菜品傳遞臺”上,其實就相當於一種通知(notify),這時服務員纔可以拿到菜並交給就餐者。
4、這一過程中出現了等待/通知 機制。
實現
方法wait():使當前執行代碼的線程進行等待,是Object類的方法。該方法用來將當前線程置入“預執行隊列”中,並且在wait()所在的代碼處停止執行,直到接到通知或被中斷爲止。
注意
在調用wait()之前,線程必須獲得該對象的對象級別的鎖,即只有在同步方法或同步代碼塊中才能使用wait()方法,否則會拋出異常。在執行完wait()之後,當前線程釋放鎖。方法notify():在同步方法或同步代碼塊中才能調用。該方法用來通知那些可能等待對象該對象的對象鎖的其他線程,如果多個線程等待,則由線程規劃器隨機挑選其中一個呈等待狀態的線程,對其發出notify通知,並使它獲得該對象的對象鎖。注意:在執行notify()之後,當前線程不會馬上釋放該對象鎖,而使等到執行notify()方法的線程將程序執行完,也就是退出synchronized代碼塊後,當前線程纔會釋放鎖,呈wait狀態所在線程纔可以獲得該對象的對象鎖。
public class MyThread1 extends Thread{
private Object lock;
public MyThread1(Object lock){
super();
this.lock=lock;
}
public void run(){
try {
synchronized (lock) {
System.out.println("開始 wait time="+System.currentTimeMillis());
lock.wait();
System.out.println("結束 wait time="+System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread2 extends Thread{
private Object lock;
public MyThread2(Object lock){
super();
this.lock=lock;
}
public void run(){
synchronized (lock) {
System.out.println("開始 notify time="+System.currentTimeMillis());
lock.notify();
System.out.println("結束 notify time="+System.currentTimeMillis());
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Object lock=new Object();
MyThread1 m1=new MyThread1(lock);
m1.start();
Thread.sleep(3000);
MyThread2 m2=new MyThread2(lock);
m2.start();
}
}
運行結果:
開始 wait time=1449836693399
開始 notify time=1449836696401
結束 notify time=1449836696401
結束 wait time=1449836696401