wait():让线程等待的方法。
notify和notifyAll():唤醒等待中的线程的方法。
等待队列:所有实例都拥有一个等待队列,在执行wait方法后,线程便会暂停操作,进入等待队列这个休息室。除非发生下列某一情况,否则线程会一直在等待队列中休眠。当下列任意一种情况发生时,,线程便会退出等待队列。
- 有其他线程的notify方法来唤醒线程
- 有其他线程的notifyAll方法来唤醒线程
- 有其他线程的interrupt方法来唤醒线程
wait()方法:
wait(等待)方法会让线程进入等待队列。假设我们执行了下面这条语句。
obj.wait();
那么,当前线程便会暂停运行,并进入实例obj的等待队列中。这叫作“线程正在obj上wait”.
若要执行wait方法,线程必须持有锁(这是规则)。但如果线程进入等待队列,便会释放其实例的锁。整个操作过程如下:
- 获取了锁的线程A执行wait方法:
2.线程A进入等待队列,释放锁:
3.线程B能够获取锁:
notify方法-从等待队列中取出线程
notify(通知)方法将会等待队列中的一个线程取出。假设我们 执行了下面这条语句。
obj.notify();
那么obj的等待队列中的一个线程便会被选中和唤醒,然后就会退出等待队列。
整个操作过程如下:
1. 获取了锁的线程B执行notify方法
2.线程A退出等待队列,想要进入wait的下一个操作,但刚才执行notify的线程B扔持有锁
3.刚才执行notify的线程B释放了锁:
4.退出等待队列 的线程A获取锁,执行wait的下一个操作:
同wait方法一样,若要执行notify方法,线程也必须持有要调用的实例的锁(这是规则)。
执行notify后的线程状态:
notify唤醒的线程并不会在执行notify的一瞬间重新运行,因为在执行notify的那一瞬间,执行notify的线程还持有锁,所以其他线程还无法获取这实例的锁。
执行notify后如何选择线程:
加入在执行notify方法时,正在等待队列中等待的线程不止一个,对于“这个该如何来选择线程”这个问题规范中并没有作出规定,究竟是选择最先wait的线程还是随机选择,或者采用其他方法要取决于Java平台运行环境。因此编程程序时需要注意,最好不要编写依赖于所选线程的程序。
notifyAll方法-从等待队列中取出所有线程
notifyAll(通知大家)方法会将等待队列中的所有线程都取出来。例如,执行下面这条语句之后,在obj实例的等待队列中休眠的所有线程 都会被唤醒。
obj.notifyAll();
notify方法仅唤醒 一个线程,而notifyAll则唤醒所有线程,这是两者之间唯一的区别;
1.notify方法仅唤醒一个线程,并让该线程退出等待队列:
2.notifyAll方法唤醒所有线程,并让所有线程都退出等待队列:
注:如果未持有锁的线程调用wait、notify或notifyAll,异常java.lang.IllegalMonitorStateException会被抛出。