wait()notify()都是Object对象上的方法,因此可以在任何对象上调用。

在一个对象上调用wait()方法后,线程就进入对象的等待队列,即线程在该对象上等待,直到其它线程调用了该对象的notify()notifyAll()方法。

一个对象的等待队列可能有多个线程,即多个线程都在等待这个对象。notify()会随机唤醒等待队列上的一个线程,而notifyAll()则会唤醒等待队列上的所有线程。

必须在获得对象锁的前提下(即在synchronized语句中)才可以调用对象的wait()notify()方法。

wait()方法在执行前需先获得对象锁,执行后会自动释放对象锁;notify()方法在执行前需先获得对象锁,但并不会直接释放锁,而是正常执行。被唤醒的线程并不能立即继续执行,在执行前还是需要先获得对象锁。

import java.util.concurrent.TimeUnit;

public class WaitNotifyDemo {
  public static void main(String[] args) {
    final Object object = new Object();

    Thread t1 = new Thread("t1") {
      @Override
      public void run() {
        synchronized (object) {
          System.out.println(
              Thread.currentThread().getName() + ", start at " + System.currentTimeMillis());
          try {
            object.wait();
          } catch (InterruptedException e) {
            System.out.println(e.getStackTrace());
          }
          System.out
              .println(Thread.currentThread().getName() + ", end at " + System.currentTimeMillis());
        }
      }
    };

    Thread t2 = new Thread("t2") {
      @Override
      public void run() {
        synchronized (object) {
          System.out.println(
              Thread.currentThread().getName() + ", start at " + System.currentTimeMillis());
          object.notify();
          try {
            TimeUnit.SECONDS.sleep(2);
          } catch (InterruptedException ex) {
            System.out.println(ex.getStackTrace());
          }
          System.out
              .println(Thread.currentThread().getName() + ", end " + System.currentTimeMillis());
        }
      }
    };
    
    t1.start();
    t2.start();
  }
}