我不完全理解waitnotifyObject的)的工作方式,因此,我不得不将尝试减少到​​以下代码部分。

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,但是我不明白为什么。从我所看到的,我需要同步Runner.run,但是这样做的话,我假设它只通知一个线程,而这个想法是通知所有线程。

我看过java.util.concurrent,但是找不到合适的替代品(也许我只是缺少了一些东西)。

最佳答案

除非当前线程拥有该对象的监视器,否则您不能在该对象上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()

Javadocs for wait()提到:


此方法只能由作为该对象的监视器的所有者的线程调用。有关线程可以成为监视器所有者的方式的说明,请参见notify方法。

抛出:

IllegalMonitorStateException –如果当前线程不是此对象的监视器的所有者。


notify()


线程成为以下三个对象之一的对象的监视器的所有者
方法:


通过执行该对象的同步实例方法。
通过执行在对象上同步的synchronized语句的主体。
对于Class类型的对象,通过执行该类的同步静态方法。

10-08 09:29
查看更多