我正在尝试使用在ElevatorController类中共享数据的Person和Elevator线程来实现电梯模拟器。我的一般实现是我让每个Person存储一个控制器变量,并从那里,他们请求乘坐电梯(当前楼层到其他楼层)。控制器跟踪请求,电梯线程要求控制器根据请求生成新的分配(停止在哪个楼层和方向)。我遇到麻烦的部分是门在地板上打开的通知。我已经尝试在ElevatorController中放置一个布尔数组,并让Person线程调用wait()(在controller.areDoorsOpen上的synchronized块内),然后从控制器调用areDoorsOpen数组上的notifyAll,但我一直得到IllegalMonitorStateExceptions。我的想法是当Person线程被通知时(控制器在更改areDoorsOpen数组中的条目时这样做),他们检查布尔数组以查看门是否在他们的地板上打开(或者如果他们在电梯中,他们的目的地楼层)并进入(或退出)电梯或继续等待。我的问题是为什么我在runnable人的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();
}
}
Elevator线程调用notifyOpenDoors,如果它们位于其赋值中的楼层(存储为整数数组),然后休眠3秒并调用notifyClosedDoors 如果您需要进一步澄清,请提前感谢您的帮助,并告诉我们。
答案 0 :(得分:1)
来自IllegalMonitorStateExceptions的堆栈跟踪将告诉您它的来源 - 一个重要的线索。
我相信您需要重新考虑调用wait()和notifyAll()的对象。例如,您可能希望始终使用areDoorsOpenOn.notifyAll()和areDoorsOpenOn.wait()。目前,您正在调用Runnable上的wait,并在控制器上调用notifyAll。