无法在wait()上放置一个线程 - IllegalMonitorStateException

时间:2013-05-01 22:49:45

标签: java multithreading illegalmonitorstateexcep

背景

我有一个微型机器人(这些扩展Thread类)的应用程序,它们在地图的节点处相互交易。我正在尝试编程进入节点的逻辑。节点负责携带 在节点上遇到的两个机器人之间的交易。

我想要编码到节点中的逻辑如下:

  • Bot A到了。
  • IF 节点上还有另一个Bot(例如Bot B)
  • 然后在Bot A和Bot B之间进行交易。
  • ELSE 告诉Bot A等到另一个Bot到达节点。

我的尝试

这是我尝试编码上述逻辑。

public void trade(StrippedBot trader)
{
    // check to see if there are any other bots waiting
    if(bots.size() > 0)
    {
        for (StrippedBot b : bots.keySet()) {
            if(!b.equals(trader) && !b.getFamily().getName().equals(trader.getFamily().getName()))
            {
                b.notify();
                trader.getResource().adjust(COOPERATION_REWARD);
                b.getResource().adjust(COOPERATION_REWARD);
                trace(trader);
            }
        }
    } else {
        // this is the first bot here, so shall wait for others to come.
        try
        {
            bots.put(trader, true); // keeping track - true to mean this bot is on wait().
            trader.wait(); // Tell Bot to wait till another bot comes along.
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

但是当我运行它时,我会在IllegalMonitorStateException行上获得trader.wait()。我研究过,显然这是一个常见的问题。所以我尝试了synchronized(trader),但这只是冻结了一切,我甚至无法调试代码,因为一切都被冻结了。

我非常感谢一些帮助。

由于

2 个答案:

答案 0 :(得分:0)

因此您的代码被阻止了,因为您正在执行trader.wait()但没有人正在执行trader.notify()。然后,b可能是trader。从代码中无法分辨。您需要在另一个线程中等待的同一个对象上执行notify()

  

我在trader.wait()行上获得了IllegalMonitorStateException。我研究过,显然这是一个常见的问题。所以我尝试了synchronized(交易者)

右。对某个对象执行notify()wait(),您需要位于该特定对象的synchronized块内。

  • 请记住,notify()未存储。如果您执行了notify()并且wait()方法中没有人,则notify()不执行任何操作。
  • 您应该能够调试代码。 Eclipse(至少)将向您显示所有线程。向上和向下滚动,直到看到暂停的一个。然后,您可以展开它并查看它的挂起位置。
  • 随意进行System.out.println(...)样式调试,看看发生了什么。
祝你好运。

答案 1 :(得分:0)

要处理IllegalMonitorStateException:您无法在未同步的对象上调用waitnotify。您必须同步您要拨打waitnotify的对象。

但我认为您的代码还有其他问题,例如,如果您wait上的trader,则notify trader上的{{1}}。而且,我怀疑还有更多问题,但我会限制我的答案,直接解决OP问题。