wait/notify机制使用前提
拥有相同的锁的线程才能实现wait/notify机制。
wait()方法
wait()是Object类的方法,它可以使当前执行wait()方法的线程等待,在wait所在的代码处暂停执行,并释放锁,直到接到通知或被中断为止。只能在同步方法或者同步块中调用wait()方法。如果调用wait()方法时没持有适当的锁则会抛出IllegalMonitorStateException。
notify()方法
notify()是Object类的方法,在调用notify()方法之前线程必须获得锁,使用notify()时如果没持有适当的锁则会抛出IllegalMonitorStateException。该方法用来唤醒那些正在等待该锁的wait状态的其他线程,也就是执行了notify()方法后,首先走完当前notify所在的线程中的代码,然后释放锁,wait状态的某一个线程获得锁被唤醒,从wait()后面的一行代码开始继续执行。
notifyAll()方法
notifyAll()是Object类的方法,该方法会唤醒所有wait状态的线程,唤醒的顺序是执行wait()方法的倒序。
但不是所有的jvm执行notifyAll()方法时都是倒序唤醒,具体是什么顺序取决于jvm的具体实现。
总结
wait()方法使线程暂停执行,notify()方法通知暂停的方法开始执行。
wait/notify机制简单的代码实现
//执行wait()方法的线程示例
public class WaitThread extends Thread{
private Object lock;
public WaitThread(Object lock){
super();
this.lock = lock;
}
@Override
public void run(){
try{
synchronized(lock){
System.out.println("wait所在代码块-wait()方法前需要执行的代码!");
lock.wait();
System.out.println("wait所在代码块-线程被唤醒后需要执行的代码!");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//执行notify()方法的线程示例
public class NotifyThread extends Thread{
private Object lock;
public NotifyThread(Object lock){
super();
this.lock = lock;
}
@Override
public void run(){
synchronized(lock){
System.out.println("notify所在代码块-唤醒其他某个线程前需要执行的代码!");
lock.notify();
System.out.println("notify所在代码块-继续执行!");
}
}
}
//测试类
public class Test{
public static void main(String[] args){
try {
Object lock = new Object();
WaitThread waitThread = new WaitThread(lock);
waitThread.start();
Thread.sleep(1000);
NotifyThread notifyThread = new NotifyThread(lock);
notifyThread.start();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
执行输出结果:
wait所在代码块-wait()方法前需要执行的代码!
notify所在代码块-唤醒其他某个线程前需要执行的代码!
notify所在代码块-继续执行!
wait所在代码块-线程被唤醒后需要执行的代码!
参考书籍:Java多线程编程核心技术(第2版)高洪岩 著