Pergunta

Background:

I have an application of miniature robots (these extend Thread class) that make deals with one another at nodes of a map. I am trying to program the logic that goes into the node. The node is responsible for carrying out the deals between two bots that meet at the node.

The logic I want to code into the node is as follows:

  • Bot A arrives.
  • IF there is another Bot present at the node (e.g. Bot B)
  • then broker a deal between Bot A and Bot B.
  • ELSE tell Bot A to wait until another Bot arrives at the Node.

My Attempt

Here is my attempt at coding the logic described above.

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

But when I run it, I get the IllegalMonitorStateException on the trader.wait() line. I have researched, and apparently it is a commonly encountered problem. So I tried the synchronized(trader) but that just froze everything, I couldn't even debug through the code, as everything was frozen.

Foi útil?

Solução

To deal with the IllegalMonitorStateException: You cannot call wait or notify on an unsynchronized object. You must synchronize on the object you wish to call wait or notify on.

But I think your code has other issues, for example, if you wait on trader, you'll want to notify on trader. And, I suspect there are even more issues, but I'll restrict my answer to addressing the OPs direct question.

Outras dicas

So your code is blocked because you are doing a trader.wait() but no one is doing a trader.notify(). Then again maybe b is a trader. Can't tell from the code. You need to do a notify() on the same exact object you are waiting on in another thread.

I get the IllegalMonitorStateException on the trader.wait() line. I have researched, and apparently it is a commonly encountered problem. So I tried the synchronized(trader)

Right. Do notify() or wait() on an object, you need to be within a synchronized block on that particular object.

  • Remember that the notify() is not stored. If you do a notify() and no one is in the wait() method, then the notify() does nothing.
  • You should be able to debug your code. Eclipse (at least) will show you all of your threads. Scroll up and down until you see one that is paused. You can then expand it and see where it is hung.
  • Feel free to do System.out.println(...) style debugging to see what is going on.

Good luck.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top