概述
下面的方法都是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
必须要在被
synchronized关键字控制的同步代码块中,才能调用这些方法只能通过 锁对象 调用这些方法
否则报错:IllegalMonitorStateException
为什么Object类中声明这3个方法,而不是再Thread中声明?
其实这个问题很简单,由于每个对象都拥有monitor(即锁),所以让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。而不是用当前线程来操作,因为当前线程可能会等待多个线程的锁,如果通过线程来操作,就非常复杂了。