为什么这段代码会死锁?

时间:2012-06-03 12:56:17

标签: java multithreading locking

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

我尝试了不同的场景。

但是我仍然无法找到问题的原因和原因。通常它应该工作 而且我找不到debutertermine之间的死锁位置。

  public class Interblocking {
           protected object obj = object();
           private boolean condition = true;

           public synchronized void debuter() {
               synchronized(obj) {
                   while (!condition) {
                       try {
                           obj.wait();
                       } catch (InterruptedExeption ie) {}
                   }
                   condition = false;
               }
           }

           public synchronized void terminer() {
               synchronized(obj) {
                   condition = true;
                   obj.notifyAll();
               }
           }
        }

3 个答案:

答案 0 :(得分:0)

编辑(新答案)

方法wait()不释放当前Thread的所有锁。

因此,当一个线程调用debuter时,它只释放obj锁定但保持this锁定,因此其他线程无法调用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

答案 1 :(得分:0)

我猜您的代码与您的代码完全不同。

您可能希望线程进入 debuter ,等待条件为真;

基本问题是方法上的 synchronized 关键字。他们确保只有线程在您的 Interblocking

实例的任何方法中

删除方法同步

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

第二次调用 debuter 时遇到死锁,因为第一次调用 debuter 条件为false。 并且无法执行terminer ,因为 debuter 阻止

中有一个帖子

使用多级阻塞对象(在本例中为object和this)总是可疑导致死锁。

答案 2 :(得分:0)

代码不包含死锁条件。当资源图中存在循环时会发生死锁。您只有一个资源(obj),因此资源图由单个节点组成,不能包含循环。

虽然debuter可能会等待condition,但terminer永远不会等待很长时间。