猿问

Java等待和通知:IllegalMonitorStateException

Java等待和通知:IllegalMonitorStateException

我不完全了解waitnotify(的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!");
  }}

目前我在调用时遇到IllegalMonitorStateException Main.main.wait();,但我不明白为什么。从我所看到的,我需要同步Runner.run,但这样做我认为它只会通知一个线程,当想法是通知他们所有。

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


一只萌萌小番薯
浏览 394回答 2
2回答

守着星空守着你

wait()除非当前线程拥有该对象的监视器,否则不能在对象上。要做到这一点,你必须synchronize坚持:class&nbsp;Runner&nbsp;implements&nbsp;Runnable{ &nbsp;&nbsp;public&nbsp;void&nbsp;run() &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synchronized(Main.main)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main.main.wait(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(InterruptedException&nbsp;e)&nbsp;{} &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Runner&nbsp;away!"); &nbsp;&nbsp;}}同样的规则也适用于notify()/&nbsp;notifyAll()。该Javadoc文档wait()提到这一点:此方法只应由作为此对象监视器所有者的线程调用。有关notify线程可以成为监视器所有者的方式的说明,请参阅方法。抛出:IllegalMonitorStateException&nbsp;- 如果当前线程不是此对象监视器的所有者。来自notify():线程以三种方式之一成为对象监视器的所有者:通过执行该对象的同步实例方法。通过执行synchronized在对象上同步的语句的主体。对于类型的对象Class,通过执行该类的同步静态方法。

三国纷争

你打电话都wait和notifyAll不使用synchronized块。在这两种情况下,调用线程必须拥有您调用方法的监视器上的锁。从文档notify(wait并notifyAll有类似的文档,但参考notify最完整的描述):此方法只应由作为此对象监视器所有者的线程调用。线程以三种方式之一成为对象监视器的所有者:通过执行该对象的同步实例方法。通过执行在对象上同步的synchronized语句的主体。对于Class类型的对象,通过执行该类的同步静态方法。一次只有一个线程可以拥有对象的监视器。只有一个线程能够一次实际退出&nbsp;wait,notifyAll因为他们都必须再次获得相同的监视器 - 但是所有线程都会被通知,所以只要第一个线程退出同步块,下一个将获得锁等
随时随地看视频慕课网APP

相关分类

Java
我要回答