概述
多线程之间想要互相通信来协作的话,比如A
线程在做完一些事情后需要等待B
线程一个通知才能继续。这个时候就需要wait()
和notify()
方法了。
顾名思义,wait
就是等待,notify
就是唤醒,notifyAll
则是唤醒所有,interrupt
是中断wait
状态的线程。
在当前线程中调用对象的wait
方法会使得当前线程进入等待。直到该对象的notify
方法被调用。来个demo
说明一下。
注意点:在调用wait()
和notify()
之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()
和notify()
方法。
Object lock = new Object();
new Thread(() -> {
try {
System.out.println("开始wait" + LocalDateTime.now());
synchronized (lock){
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3秒后唤醒" + LocalDateTime.now());
synchronized (lock){
lock.notify();
}
}).start();
notifyAll()
经过上面的demo
叙述可以知道,其实wait()
方法就是让该线程的方法释放共享资源的锁,然后自己进入等待队列中,直到被再次唤醒。
notify()
方法则是随机唤醒等待队列中等待同一共享资源的一个线程,并使得该线程退出等待状态,进入可运行状态。
那么notifyAll()
方法就是让所有正在等待队列中等待同一共享资源的全部线程从等待状态退出,进入可运行状态。
如果wait()
方法和notify()/notifyAll()
方法不在同步方法/同步代码块中被调用,那么虚拟机会抛出java.lang.IllegalMonitorStateException
。