0
public class DeadLock {

    public static void main(String[] args) {

        final A a = new A();
        final B b = new B();

        new Thread(new Runnable(){
            @Override
            public void run() {
                 a.aMethod(b);
                }
        },"Thread-2").start();

        new Thread(new Runnable(){
            @Override
            public void run() {
                b.bMethod(a);
            }
        },"Thread-2").start();
    }
}

class A {
    public  void aMethod(B b) {
        System.out.println("A method");
    }
}

class B {
    public  void bMethod(A a) {
        System.out.println("B method");
    }
}

我知道当两个或多个线程被阻塞等待对方时会发生死锁。如何使用上面的代码实现相同的功能?同步类 A 和 B 中的方法没有帮助。

4

2 回答 2

5

如何使用上面的代码实现相同的功能?同步类 A 和 B 中的方法没有帮助。

死锁的定义是A被锁住需要锁来自B的同时B被锁住需要锁来自A

您将无法使用单个线程调用来模拟它,因为启动的第一个线程可能会在第二个线程启动之前完成。这是线程竞相死锁或不死锁的典型情况。

您需要在两个线程中循环并一遍又一遍地尝试双重锁定。像下面这样的东西应该可以工作。在某些时候,您会看到输出停止。

public void run() {
   while (true) {
     a.aMethod(b);
   }
}
...
public void run() {
   while (true) {
     b.bMethod(a);
   }
}
...
public synchronized void aMethod(B b) {
    System.out.println("B method");
    b.bMethod(this);
}
...
public synchronized void aMethod(A a) {
    System.out.println("A method");
    a.aMethod(this);
}

您可能还必须删除这些System.out.println(...)调用,因为它们synchronized也会改变您的程序的时间,并可能使遇到死锁变得更加困难。如果没有输出,要检测没有输出的死锁,您可以使用 jconsole 附加到进程,查看“线程”选项卡,然后单击“检测死锁”。您还可以查看程序的负载。它应该在 2 个线程旋转时为 ~200%,然后在它们死锁时变为 0。

于 2013-04-25T19:51:56.743 回答
1
public static void main(String[] args) {
    final Object a = new Object();
    final Object b = new Object();

    Thread t1 = new Thread() {
        @Override
        public void run() {
            synchronized (a) {
                try {
                    sleep(10000);
                } catch (InterruptedException exc) {
                    // 
                }
                synchronized (b) {
                    //
                }
            }
        }
    };

    Thread t2 = new Thread() {
        @Override
        public void run() {
            synchronized (b) {
                try {
                    sleep(10000);
                } catch (InterruptedException exc) {
                    // 
                }
                synchronized (a) {
                    //
                }
            }
        }
    };
    t1.start();
    t2.start();
}
于 2014-03-18T19:23:21.900 回答