java如何确定是否存在明显的死锁?
我有一个测试单元来测量电梯控制器类的正确性,它模拟人们进出电梯门以及电梯门的打开和关闭 我的问题是,在我的10次测试中,每个人都会调用以下失败:java如何确定是否存在明显的死锁?,java,concurrency,Java,Concurrency,我有一个测试单元来测量电梯控制器类的正确性,它模拟人们进出电梯门以及电梯门的打开和关闭 我的问题是,在我的10次测试中,每个人都会调用以下失败: java.lang.IllegalStateException: Apparent deadlock thread 1 WAITING java.lang.Object.wait(Native Method) java.lang.Object.wait(Object.java:485) lift.MyLiftController.callL
java.lang.IllegalStateException: Apparent deadlock
thread 1 WAITING
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
lift.MyLiftController.callLift(MyLiftController.java:23)
lift.MyLiftControllerMultithreadedTest1.thread1(MyLiftControllerMultithreadedTest1.java:29)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
edu.umd.cs.mtc.TestFramework$2.run(TestFramework.java:592)
java.lang.Thread.run(Thread.java:695)
at edu.umd.cs.mtc.TestFramework$1.run(TestFramework.java:483)
有时,它会这样说:
Exception in thread "thread 2" java.lang.AssertionError: thread 2 killed by thread 1
因此,我的问题是:
Java什么时候才能确定进程是否是明显的死锁?
以下是相关代码的片段:
TestLifeMultiple1.java
这是测试,运行100次
MyLiftControllerMultithreadedTest2.java
这是测试的实际内容
以下代码也在MyLiftController中,用于设置currentFloor和currentDirection。但正如您所看到的,在线程3上调用:
/* Interface for Lifts */
public synchronized boolean liftAtFloor(int floor, Direction direction) {
currentFloor = floor;
currentDirection = direction;
//if there are people who will get in or out at floor X in direction Y
if (numOfPplAtFlrInDir[floor][direction2Int(direction)]!=0 || numOfPplAtFlr[floor]!=0){
return true;
}
return false;
}
// door waits indefinitely until all people exit or enter
public synchronized void doorsOpen(int floor) throws InterruptedException {
// ask everyone to take action and wait for them to finish
notifyAll();
while (numOfPplAtFlrInDir[floor][direction2Int(currentDirection)]!=0 && numOfPplAtFlr[floor]!=0){
wait();
}
}
// while door is closed, no one is allowed to enter again
// (they will be waiting)
public void doorsClosed(int floor) {
debug("door is closed at "+floor);
//next round will start
}
我只想知道为什么我的测试会随机失败。Java如何确定是否存在明显的死锁?非常感谢你
编辑:
行动,我没有张贴我的门打开和门关闭功能。基本上,这两个wait()最终都会被doorsOpen函数通知。这是否更清楚了?这不是Java决定的。这是您正在使用的框架
至于您的bug,当您的两个线程转到
wait()
,就没有人再通知它们了。您的thread-3可以执行此操作,但现在它只需设置一些变量,而不必通知任何等待的线程。首先感谢您!但是,我想我错过了发布doorsOpen函数,该函数将在测试过程中调用,最终通知all()等待()。liftAtFloor只是更新当前楼层。我的错误。这能让你在这里再次解决问题吗?我点击了multi-threadedtc链接,但找不到任何有用的资源来解释为什么一个线程杀死了另一个线程,很难说,因为它是第三方框架。您应该查看它的配置。没有可靠的方法来检测死锁,因此很容易出现误报。哦,我现在明白了。谢谢
// Person thread 1.
public void thread1() throws InterruptedException {
// Person calls the lift to floor 4, going UP.
lift_controller.callLift(4, LiftController.Direction.UP);
// Person thread should only be here when tick 2 has occurred ...
// since this indicates the lift thread has actually opened the doors.
assertTick(2);
}
// Person thread 2.
public void thread2() throws InterruptedException {
// same as thread 1
}
public void thread3() throws InterruptedException {
// Force Lift thread to wait until person threads are blocked,
// and the different person threads have called the lift.
waitForTick(1);
for (int level = 0; level < 4; level++) {
// Level 0,1,2 and 3 ... should not open doors ... hence return False.
Assert.assertFalse(lift_controller.liftAtFloor(level, LiftController.Direction.UP));
}
// Level 4 ... should open doors ... hence return True.
Assert.assertTrue(lift_controller.liftAtFloor(4, LiftController.Direction.UP));
//.....similar stuff
// Open the doors even if incorrect previous assertion ...
lift_controller.doorsOpen(7);
lift_controller.doorsClosed(7);
}
/* Interface for People */
public synchronized void callLift(int floor, Direction direction) throws InterruptedException {
numOfPplAtFlrInDir[floor][direction2Int(direction)] ++;
// Person can only enter when they are on the right floor towards right direction,
while (floor != currentFloor || direction != currentDirection){
wait();
}
numOfPplAtFlrInDir[floor][direction2Int(direction)] --;
if (numOfPplAtFlrInDir[floor][direction2Int(direction)] == 0) {
notify();
}
debug("Someone has entered "+floor);
}
/* Interface for Lifts */
public synchronized boolean liftAtFloor(int floor, Direction direction) {
currentFloor = floor;
currentDirection = direction;
//if there are people who will get in or out at floor X in direction Y
if (numOfPplAtFlrInDir[floor][direction2Int(direction)]!=0 || numOfPplAtFlr[floor]!=0){
return true;
}
return false;
}
// door waits indefinitely until all people exit or enter
public synchronized void doorsOpen(int floor) throws InterruptedException {
// ask everyone to take action and wait for them to finish
notifyAll();
while (numOfPplAtFlrInDir[floor][direction2Int(currentDirection)]!=0 && numOfPplAtFlr[floor]!=0){
wait();
}
}
// while door is closed, no one is allowed to enter again
// (they will be waiting)
public void doorsClosed(int floor) {
debug("door is closed at "+floor);
//next round will start
}