繁体   English   中英

Java 等待并通知:IllegalMonitorStateException

[英]Java Wait and Notify: IllegalMonitorStateException

我不完全理解waitnotifyObject )是如何工作的,因此我不得不将我的尝试缩小到以下代码部分。

主要.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();
  }
}

亚军.java:

class Runner implements Runnable
{
  public void run()
  {
    try
    {
      Main.main.wait();
    } catch (InterruptedException e) {}
    System.out.println("Runner away!");
  }
}

目前我在调用Main.main.wait(); ,但我不明白为什么。 据我所知,我需要同步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()

wait()Javadocs提到了这一点:

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

抛出:

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

notify()

线程通过以下三种方式之一成为对象监视器的所有者:

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

您在不使用synchronized块的情况下调用waitnotifyAll 在这两种情况下,调用线程都必须拥有调用该方法的监视器上的锁。

来自notify的文档( waitnotifyAll有类似的文档,但请参阅notify以获得最完整的描述):

此方法只能由作为此对象监视器的所有者的线程调用。 线程通过以下三种方式之一成为对象监视器的所有者:

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

一次只有一个线程可以拥有一个对象的监视器。

notifyAll之后,一次只有一个线程能够真正退出wait ,因为它们都必须再次获取同一个监视器——但所有notifyAll都将被通知,因此一旦第一个notifyAll退出同步块,下一个线程就会退出将获取锁等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM