Java 为什么这个代码会死锁?

Java 为什么这个代码会死锁?,java,multithreading,locking,Java,Multithreading,Locking,我需要一些关于死锁的帮助。我只是不明白为什么我的代码在这里死锁 我尝试了不同的场景 然而,我仍然无法找到问题的原因和所在。正常情况下,它应该能工作 我也不知道初次亮相和终结之间的僵局在哪里 编辑新答案 方法wait不会释放当前线程的所有锁 所以当一个线程调用debuter时,它只释放obj锁,但保持这个锁,这样其他线程就不能调用terminer方法 下面是一个例子: class WaitReleaseTest implements Runnable { Object lockA, loc

我需要一些关于死锁的帮助。我只是不明白为什么我的代码在这里死锁

我尝试了不同的场景

然而,我仍然无法找到问题的原因和所在。正常情况下,它应该能工作 我也不知道初次亮相和终结之间的僵局在哪里

编辑新答案 方法wait不会释放当前线程的所有锁

所以当一个线程调用debuter时,它只释放obj锁,但保持这个锁,这样其他线程就不能调用terminer方法

下面是一个例子:

class WaitReleaseTest implements Runnable {
    Object lockA, lockB;
    public WaitReleaseTest(Object lockA, Object lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName()
                + " attempting to acquire lockA");
        synchronized (lockA) {
            System.out.println(Thread.currentThread().getName()
                    + " attempting to acquire lockB");
            synchronized (lockB) {
                System.out.println(Thread.currentThread().getName()
                        + " holds lockA = " + Thread.holdsLock(lockA));
                System.out.println(Thread.currentThread().getName()
                        + " holds lockB = " + Thread.holdsLock(lockB));
                try {
                    lockB.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object o1=new Object();
        Object o2=new Object();
        new Thread(new WaitReleaseTest(o1,o2)).start();
        TimeUnit.MILLISECONDS.sleep(500);
        new Thread(new WaitReleaseTest(o1,o2)).start();
    }
}
输出

Thread-0 attempting to acquire lockA
Thread-0 attempting to acquire lockB
Thread-0 holds lockA = true
Thread-0 holds lockB = true
Thread-1 attempting to acquire lockA
... now it waits

我猜你的代码与你的代码完全不同

您可能希望线程进入首次公开,直到条件为真

基本问题是方法上的synchronized关键字。它们确保只有线程在互锁实例的任何方法中

删除方法上的同步

下一个问题是条件。在调用terminer之后,线程如何释放还未定义

你在第二次登场时遇到死锁,因为在第一次登场后条件为false。 并没有办法执行terminer,因为在debuter阻塞中有一个线程


在这种情况下,使用多个级别的阻塞对象会导致死锁。代码不包含死锁条件。当资源图中存在循环时,就会发生死锁。您只有一个资源对象,因此资源图由单个节点组成,不能包含循环


虽然初次亮相可能会等待条件,但terminer从不等待很长时间。

好吧,既然你还没有说这个类的目的是什么,很难回答这个问题……为什么下面指定的类描述了一个典型的死锁情况?给出一个说明这种默认情况的场景。这就是问题所在;我在理解上有困难吗?这是家庭作业吗?如果是这样,请将其标记为家庭作业。此外,如果有一些线程正在执行某些操作,则可能会出现死锁。你的线程和这个类有什么关系?是的,这是一个家庭作业,给出的语句是我之前解释的,我不知道线程在做什么,我只知道必须有线程1 T1,线程2 T2,线程3 T3。。。我非常感谢你,因为我知道这是绕道的解决方案deadlocking@Dardan我没有权利,所以我的答案不能解决你的问题。那么这是正确的吗?这里有两个锁:类interblocing的实例,因为您使用的是同步方法。obj的实例,因为您正在使用SynchronizeDBJ,然后等待并通知它。现在,如果线程A转到debuter方法并等待obj,那么线程B不能转到terminer执行obj.notifyAll,因为线程A仍然持有interblocing类实例的监视器锁。“因此它会死锁。”Dardan你刚才回答了你的问题。我以为等待会释放所有线程锁,但它不会。因此,当一个线程调用debuter时,它只释放obj锁,但保持该锁,这样其他线程就不能调用terminer。我不必让这段代码工作,我只需要回答为什么这段代码执行死锁谢谢uThat是错误的。当线程在首次公开时,terminer将不会被执行。是的,我错了。我只是注意到这个和obj上的方法都是同步的。应仅对一个对象(此对象或obj)进行同步。
Thread-0 attempting to acquire lockA
Thread-0 attempting to acquire lockB
Thread-0 holds lockA = true
Thread-0 holds lockB = true
Thread-1 attempting to acquire lockA
... now it waits