Там есть несколько хороших постов, есть много альтернатив, но я думаю, что это какое-то академическое упражнение?Как отмечали люди, вы, вероятно, не использовали бы wait / notify / notifyAll, когда есть более современные альтернативы, которые облегчают работу.Хотя ожидание / уведомление интересны и их стоит понять как основу для параллельной работы.
Я предполагаю, что это какая-то вещь для потребителя / производителя?Один поток захватывает сканер, другой освобождает его?Если это так, возможно, вы захотите подождать, пока в ловушке появятся пассажиры, прежде чем освободить их?это может выглядеть примерно так ...
private final List<Object> trap = new ArrayList<Object>();
public class BugCatcher {
public void trapCrawler(Object crawler) {
synchronized (trap) {
trap.add(crawler);
System.out.println("caught bug number " + trap.size() + "!");
trap.notifyAll();
}
}
}
public class Hippy {
public void setCrawlerFree(Object crawler) throws InterruptedException {
synchronized (trap) {
trap.wait();
trap.clear();
System.out.println("set bugs free! time to hug a tree");
}
}
}
Если BugCatcher
может ловить ошибки быстрее, чем хиппи их выпускает, хиппи ждет, пока в ловушке что-то есть, прежде чем пытаться освободить ошибки(следовательно, wait
вызов).
Если вы пропустите часть ожидания / уведомления, все будет зависеть только от ключевого слова synchronized
, только один поток будет получать доступ к ловушке за раз, и это будет гонка за тем, кто попадет первым (хиппиможет попробовать пустую уже пустую ловушку).
Для координации ожидания и уведомления виртуальная машина будет использовать объектный монитор.Поток получает монитор объекта, когда входит в синхронизированный блок.У объекта есть только один монитор, который действует как взаимоисключающий замок (мьютекс).Если вы попытаетесь и wait
или notify
без предварительного получения монитора объекта (без выполнения wait
или notify
в синхронизированном блоке), виртуальная машина не сможет что-то настроить и выдает IllegalMonitorException
.Он говорит: «Я не могу этого допустить, потому что, если, например, я подожду, когда я узнаю, что могу прогрессировать, когда кто-то звонит, уведомляет? Что / кого они уведомляют?».Он использует монитор для координации и вынуждает вас захватывать монитор.
Итак, ошибка, которую вы получаете, заключается в том, что numToGo
не синхронизирован в другом потоке (как ранее говорил Майкл).
Я не могу понять, зачем вам нужен numToGo
, если это производитель / потребитель, вы хотите остановиться после определенного числа?После того, как ловец ошибок ловит 10 ошибок, а хиппи выпускает 10?Не похоже, что это то, что вы пытаетесь сделать (так как они могут иметь не связанные между собой внутренние счетчики), поэтому я не уверен, что вы пытаетесь сделать там.Было бы неплохо обрисовать, что вы пытаетесь сделать, если я ушел совсем по другому!