0

背景:

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

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

  • 机器人 A 来了。
  • 如果节点上存在另一个 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();
        }
    }
}

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

4

2 回答 2

0

因此,您的代码被阻止,因为您正在执行 atrader.wait()但没有人在执行trader.notify(). 然后又可能b是一个trader. 从代码上看不出来。您需要对notify()您在另一个线程中等待的同一个对象执行 a 。

我得到了IllegalMonitorStateExceptiontrader.wait() 行。我研究过,显然这是一个常见的问题。所以我尝试了同步(交易者)

正确的。做notify()wait()在一个对象上,您需要synchronized在该特定对象的一个​​块内。

  • 请记住,notify()不存储。如果你做了一个notify()并且没有人在wait()方法中,那么notify()什么都不做。
  • 您应该能够调试您的代码。Eclipse(至少)会显示你所有的线程。向上和向下滚动,直到您看到一个暂停。然后您可以展开它并查看它挂在哪里。
  • 随意进行System.out.println(...)样式调试以查看发生了什么。

祝你好运。

于 2013-05-01T23:51:23.290 回答
0

处理IllegalMonitorStateException:你不能调用waitnotify在一个不同步的对象上。您必须在要调用的对象上进行wait同步notify

但我认为您的代码还有其他问题,例如,如果您waiton trader,您会想要notifyon trader。而且,我怀疑还有更多问题,但我会限制我的回答来解决 OP 的直接问题。

于 2013-05-02T03:39:34.610 回答