等待/通知机制
等待/通知机制在生活中比比皆是,举一个例子,厨师与服务员的例子,他们之间的交互在“菜品传递台”。
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