java如何确定是否存在明显的死锁?

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

我有一个测试单元来测量电梯控制器类的正确性,它模拟人们进出电梯门以及电梯门的打开和关闭

我的问题是,在我的10次测试中,每个人都会调用以下失败:

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
}