Не могу поставить поток на 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(...)
отладка стиля, чтобы увидеть, что происходит.
Удачи.