-2

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

我尝试了不同的场景。

但是我仍然找不到问题的原因和位置。通常它应该可以工作,我找不到死锁在debuter和之间的位置termine

  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();
               }
           }
        }
4

3 回答 3

0

编辑(新答案)

方法wait()不会释放当前线程的所有锁。

所以当一个线程调用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
于 2012-06-03T13:52:24.027 回答
0

我猜您的代码与您的代码能够执行的操作完全不同。

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

基本问题是方法上的同步关键字。他们确保只有线程在您的Interblocking实例的任何方法中

删除方法上的同步

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

你在第二次调用中遇到了死锁,因为在第一次调用之后条件false。并且没有办法执行终止程序,因为在debuter阻塞中有一个线程

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

于 2012-06-03T14:47:29.380 回答
0

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

虽然debuter可以等待conditionterminer但从不等待很长时间。

于 2012-06-03T15:09:35.310 回答