wait和notify方法
wait方法和notify方法是Object类的方法,用以支持线程间通信。
1、wait方法
以下是wait方法的三个重载方法:
public final void wait() throws InterruptedExeception
public final void wait(long timeout) throws InterruptedExeception
public final void wait(long timeout,int nanos) throws InterruptedExeception
- wait方法的三个重载方法都将调用wait(long timeout)方法,wait()等价于wait(0),代表永不超时。
- Object的wait(long timeout)方法会导致当前线程进入阻塞,知道其他线程调用了该Object的notify()或notifyAll()方法才能将其唤醒,或者阻塞到达了timeout时间而自动唤醒。
- wait方法必须拥有该对象的monitor,也就是wait方法必须在同步方法中使用。
- 当前线程执行了对象的wait方法之后,将会放弃对该monitor的所有权比进入该对象关联的wait set中,也就是说wait方法会释放锁。
2、notify方法
public final native void notify();
- notify方法唤醒单个只在执行该对象wait方法的线程,notifyAll方法唤醒全部。
- 如果某个线程由于执行该对象的wait方法而进入阻塞则会被唤醒,如果没有则会被忽略。
- 被唤醒的线程需要重新获得该对象关联的monitor的锁才能继续执行。
3、使用wait和notify方法的注意事项
- wait方法是可中断方法。当前线程调用wait方法进入阻塞状态,其他线程可以使用interrupt方法将其打断。可中断方法被打断后会收到中断异常InterruptedException,同时interrupt标识会被擦除。
- 线程执行了某个对象的wait方法后,会加入与之对应的wait set中,每一个对象的monitor都有一个与之关联的wait set。
- 必须在同步方法中使用wait和notify方法,因为执行wait和notify方法的前提条件是必须持有同步方法的monitor的所有权。
- 同步代码锁的对象必须与执行wait和notify方法的对象一致。
4、wait和sleep的异同
- wait和sleep方法都可以使线程进入阻塞状态
- wait和sleep方法都是可中断方法,被中断后都会收到中断异常
- wait是Object的方法,sleep是Thread的方法
- wait方法必须在同步代码中执行,而sleep不需要
- 在同步代码中执行sleep方法时,不会释放锁,而wait方法会释放锁
- sleep方法休眠后会主动退出阻塞,而wait方法(未指定等待时间)则需要被其他线程中断或唤醒才能退出阻塞