我正在尝试使用共享ElevatorController类中的数据的Person和Elevator线程实现一个电梯模拟器。我的一般实现是,我让每个人都存储一个控制器变量,然后他们从那里请求乘坐电梯(当前楼层到其他楼层)。控制器跟踪请求,而Elevator线程向控制器请求新的分配(该楼层将在哪个楼层停止并指向),该分配将根据请求生成。我遇到麻烦的部分是关于门在地板上打开的通知。我试过在ElevatorController中放置一个布尔数组,并让Person线程调用wait()(在controller.areDoorsOpen的同步块内),然后从控制器的areDoorsOpen数组上调用notifyAll,但是我一直在获取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
预先感谢您的帮助,如果您需要进一步的澄清,请告诉我。

最佳答案

来自IllegalMonitorStateExceptions的堆栈跟踪将告诉您它的来源-一个重要的线索。

我相信您需要重新考虑正在调用wait()和notifyAll()的对象。例如,您可能希望始终使用areDoorsOpenOn.notifyAll()和areDoorsOpenOn.wait()。当前,您正在Runnable上调用wait,而在Controllers上调用notifyAll。

09-11 17:50