Уведомления в симуляторе лифта на Java
Я пытаюсь реализовать симулятор лифта с потоками Person и Elevator, которые совместно используют данные в классе ElevatorController. Моя общая реализация состоит в том, что у меня каждый Person хранит переменную контроллера, и оттуда они запрашивают поездку в лифте (с текущего этажа на другой этаж). Контроллер отслеживает запросы, а потоки Elevator запрашивают у контроллера новое назначение (на каких этажах остановиться и в каком направлении), которое он генерирует на основе запросов. У меня проблема с уведомлением о том, что двери на полу открыты. Я попытался поместить логический массив в ElevatorController и заставить потоки Person вызывать wait() (в синхронизированном блоке на controller.areDoorsOpen), а затем вызывать notifyAll для массива areDoorsOpen из контроллера, но я продолжаю получать IllegalMonitorStateExceptions. Моя идея состояла в том, что, когда потоки Person уведомляются (контроллер делает это, когда он изменяет запись в массиве areDoorsOpen), они проверяют логический массив, чтобы видеть, открыта ли дверь на их этаже (или если они находятся в лифте, на этаж назначения) и войдите (или выйдите) в лифт или продолжайте ожидание. У меня вопрос: почему я получаю это исключение при вызове wait () в человеке, который работает?
Изменить: соответствующий код
В лице Runnable,
private void waitForElevator() {
synchronized (controller.areDoorsOpenOn) {
System.out.printf("Person %d is waiting on floor %d to go to floor %d.\n", ID, currentFloor, destinationFloor);
while(!controller.areDoorsOpenOn[currentFloor]) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
В классе контроллера
public boolean[] areDoorsOpenOn = new boolean[numberOfFloors];
public void notifyOpenDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = true;
notifyAll();
}
}
public void notifyClosedDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = false;
notifyAll();
}
}
Потоки лифта вызывают notifyOpenDoors, если они находятся на этаже, который находится в их назначении (хранится как массив целых чисел), а затем спят в течение 3 секунд и вызывают notifyClosedDoors Заранее спасибо за вашу помощь и дайте мне знать, если вам нужны какие-либо дополнительные разъяснения,
1 ответ
Трассировка стека от IllegalMonitorStateExceptions скажет вам, откуда это происходит - важный ключ.
Я считаю, что вам нужно переосмыслить, какие объекты вы вызываете wait() и notifyAll(). Например, вы можете всегда использовать areDoorsOpenOn.notifyAll() и areDoorsOpenOn.wait(). В настоящее время вы вызываете wait для Runnable и notifyAll для контроллеров.