Уведомления в симуляторе лифта на 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 для контроллеров.

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