线程等待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方法并没有把锁释放了。