Java等待并通知:IllegalMonitorStateException
我不完全了解wait和notify ( Object )的工作,结果我不得不削减我的尝试到下面的代码段。 
Main.java:
 import java.util.ArrayList; class Main { public static Main main = null; public static int numRunners = 4; public static ArrayList<Runner> runners = null; public static void main(String[] args) { main = new Main(); } Main() { runners = new ArrayList<Runner>(numRunners); for (int i = 0; i < numRunners; i++) { Runner r = new Runner(); runners.add(r); new Thread(r).start(); } System.out.println("Runners ready."); notifyAll(); } } 
Runner.java:
 class Runner implements Runnable { public void run() { try { Main.main.wait(); } catch (InterruptedException e) {} System.out.println("Runner away!"); } } 
 目前,我调用Main.main.wait();时,我得到一个IllegalMonitorStateException Main.main.wait();  ,但我不明白为什么。 从我所能看到的,我需要同步Runner.run ,但是这样做,我认为它只会通知一个线程,当想法是通知他们所有。 
 我已经看了java.util.concurrent ,但我找不到合适的replace(也许我只是缺less一些东西)。 
 除非当前线程拥有该对象的监视器,否则不能wait()对象wait() 。 要做到这一点,你必须synchronize : 
 class Runner implements Runnable { public void run() { try { synchronized(Main.main) { Main.main.wait(); } } catch (InterruptedException e) {} System.out.println("Runner away!"); } } 
 同样的规则也适用于notify() / notifyAll() 。 
  wait()的Javadocs提到了这个: 
这个方法只能由这个对象监视器的所有者的线程调用。 有关线程可以成为监视器所有者的方式的说明,请参阅
notify方法。抛出:
IllegalMonitorStateException– 如果当前线程不是此对象监视器的所有者。
 并从notify() : 
线程以三种方式之一成为对象监视器的所有者:
- 通过执行该对象的同步实例方法。
- 通过执行同步对象的
synchronized语句的主体。- 对于types为
Class对象,通过执行该类的同步静态方法。
 您正在调用wait和notifyAll而不使用synchronized块。 在这两种情况下,调用线程都必须拥有调用该方法的监视器上的locking。 
 从notify文档( wait和notifyAll有类似的文档,但参考notify的最完整的描述): 
这个方法只能由这个对象监视器的所有者的线程调用。 线程以三种方式之一成为对象监视器的所有者:
- 通过执行该对象的同步实例方法。
- 通过执行同步对象的同步语句的主体。
- 对于types为Class的对象,通过执行该类的同步静态方法。
一次只有一个线程可以拥有一个对象的监视器。
 在notifyAll之后,只有一个线程能够实际退出 wait ,因为它们都必须再次获取相同的监视器 – 但是所有的线程都会被通知,所以一旦第一个notifyAll退出同步块,下一个将获得锁等