本文介绍了Java 等待和通知:IllegalMonitorStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不完全理解 waitnotify(Object)是如何工作的,因此我被迫瘦身将我的尝试归结为以下代码部分.

I don't completely understand how wait and notify (of Object) work, and as a result I'm forced to slim down my attempts into the following section of code.

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:

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,但这样做时我假设它只会通知一个线程,而想法是通知所有线程.

Currently I get an IllegalMonitorStateException when calling Main.main.wait();, but I don't understand why. From what I can see, I need to synchronize Runner.run, but in doing so I assume it would only notify one thread, when the idea is to notify them all.

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

I've looked at java.util.concurrent, but I can't find a suitable replacement (maybe I'm just missing something).

推荐答案

除非当前线程拥有该对象的监视器,否则您不能在该对象上wait().为此,您必须对其进行同步:

You can't wait() on an object unless the current thread owns that object's monitor. To do that, you must synchronize on it:

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

同样的规则也适用于 notify()/notifyAll().

The same rule applies to notify()/notifyAll() as well.

Javadocs wait() 提到这个:

此方法只能由作为此对象监视器所有者的线程调用.请参阅 notify 方法以了解线程可以成为监视器所有者的方式.

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

IllegalMonitorStateException – if the current thread is not the owner of this object's monitor.

来自notify():

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

  • 通过执行该对象的同步实例方法.
  • 通过执行在对象上同步的 synchronized 语句的主体.
  • 对于 Class 类型的对象,通过执行该类的同步静态方法.
  • By executing a synchronized instance method of that object.
  • By executing the body of a synchronized statement that synchronizes on the object.
  • For objects of type Class, by executing a synchronized static method of that class.

这篇关于Java 等待和通知:IllegalMonitorStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:09
查看更多