JAVA wait()、notify()、notifyAll() 作者:马育民 • 2020-01-29 16:05 • 阅读:10088 # 概述 下面的方法都是Object类的方法 # wait() 让当前线程阻塞 调用wait()方法,相当于让当前线程 **释放** **此对象的锁**(monitor),然后进入等待状态,等待后续再次获得此对象的锁 (Thread.sleep()方法使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但它并不释放对象锁); ``` public final native void wait(long timeout) throws InterruptedException; ``` 下面两个方法底层都是调用上面的方法 ``` public final void wait() throws InterruptedException ``` ``` public final void wait(long timeout, int nanos) throws InterruptedException ``` ### 注意 调用某个对象的wait()方法,当前线程必须拥有这个对象的 锁(monitor) 因此调用wait()方法必须在 **同步块** 或者 **同步方法** 中进行(synchronized块或者synchronized方法)。 如果当前线程没有这个对象的锁就调用wait()方法,则会抛出IllegalMonitorStateException. # notify() 和 notifyAll() ### notify() 能够唤醒一个正在等待该对象的 锁(monitor)的线程,当有多个线程都在等待该对象的 锁(monitor)的话,则只能唤醒其中一个线程,具体唤醒哪个线程则不得而知。 ##### 注意 调用某个对象的notify()方法,当前线程也必须拥有这个对象的 锁(monitor),因此调用notify()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)。 ``` public final native void notify(); ``` 唤醒所有正在等待这个对象的monitor的线程 ### notifyAll() 能够唤醒所有正在等待该对象的 锁(monitor)的线程 ``` public final native void notifyAll(); ``` 唤醒所有正在等待这个对象的monitor的线程 ### 注意: notify()和notifyAll()方法只是唤醒等待该对象的monitor的线程,并不决定哪个线程能够获取到monitor。 # XX使用注意XX 1. 必须要在被 `synchronized` 关键字控制的同步代码块中,才能调用这些方法 2. 只能通过 **锁对象** 调用这些方法 否则报错:`IllegalMonitorStateException` # 为什么Object类中声明这3个方法,而不是再Thread中声明? 其实这个问题很简单,由于每个对象都拥有monitor(即锁),所以让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。而不是用当前线程来操作,因为当前线程可能会等待多个线程的锁,如果通过线程来操作,就非常复杂了。 原文出处:http://malaoshi.top/show_1EF4t16wH42H.html