Не могу поставить поток на wait() - IllegalMonitorStateException

Фон:

У меня есть приложение миниатюрных роботов (они расширяют Thread класс), которые заключают сделки друг с другом в узлах карты. Я пытаюсь запрограммировать логику, которая входит в узел. Узел отвечает за выполнение сделок между двумя ботами, которые встречаются в узле.

Логика, которую я хочу закодировать в узел, выглядит следующим образом:

  • Бот А прибывает.
  • Если в узле присутствует другой бот (например, бот B)
  • затем заключите сделку между Ботом А и Ботом Б.
  • В противном случае попросите бота А подождать, пока другой бот не прибудет на узел.

Моя попытка

Вот моя попытка кодирования логики, описанной выше.

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 ответа

Решение

Иметь дело с IllegalMonitorStateException: Вы не можете позвонить wait или же notify на несинхронизированном объекте. Вы должны синхронизироваться на объекте, который вы хотите вызвать wait или же notify на.

Но я думаю, что у вашего кода есть другие проблемы, например, если вы wait на traderты захочешь notify на trader, И я подозреваю, что есть еще больше проблем, но я ограничу свой ответ на прямой вопрос ОП.

Таким образом, ваш код заблокирован, потому что вы делаете trader.wait() но никто не делает trader.notify(), Тогда опять может быть b это trader, Не могу сказать из кода. Вам нужно сделать notify() на тот же самый объект, который вы ожидаете в другом потоке.

Я получаю IllegalMonitorStateException на линии trader.wait(). Я исследовал, и, видимо, это часто встречающаяся проблема. Поэтому я попробовал синхронизированный (трейдер)

Правильно. Делать notify() или же wait() на объекте, вы должны быть в пределах synchronized блок на этом конкретном объекте.

  • Помните, что notify() не сохраняется Если вы делаете notify() и никто не в wait() метод, то notify() ничего не делает.
  • Вы должны быть в состоянии отладить свой код. Затмение (по крайней мере) покажет вам все ваши темы. Прокручивайте вверх и вниз до тех пор, пока не увидите паузу. Затем вы можете расширить его и посмотреть, где он висит.
  • Не стесняйтесь делать System.out.println(...) отладка стиля, чтобы увидеть, что происходит.

Удачи.

Другие вопросы по тегам