我不完全理解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,但是我不明白为什么。从我所看到的,我需要同步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
类型的对象,通过执行该类的同步静态方法。