在多线程中混淆输出显示死锁?

时间:2012-08-28 17:16:10

标签: java multithreading

我刚刚编译并运行了java程序,但输出结果令人不快。 我不知道为什么线程处于死锁状态。 任何人都可以帮助我理解程序的输出。

class A {
synchronized void foo(B b) {
    String name=Thread.currentThread().getName();
    System.out.println(name+"entered A.foo");

    try {
        Thread.sleep(1000);
    } catch(Exception e) {}
    System.out.println(name+"trying to call B.last()");
    b.last();
}
synchronized void last() {
    System.out.println("inside A.last");
}
}

class B {
synchronized void bar(A a) {
    String name=Thread.currentThread().getName();
    System.out.println(name+"entered B.bar");
    try {
        Thread.sleep(1000);
    } catch(Exception e) {
        System.out.println("b interrupted");
    }
    System.out.println(name+"trying to call A.last()");
    a.last();
}
synchronized void last() {
    System.out.println("inside A.last");
}
}

class DeadLock implements Runnable {
A a=new A();
B b=new B();
DeadLock() {
    Thread.currentThread().setName("mainthread");
    Thread t=new Thread(this,"racingthread");
    t.start();
    a.foo(b);
    System.out.println("back in main thread");
}
public void run() {
    b.bar(a);
    System.out.println("back in other theread");
}
public static void main(String...d) {
    new DeadLock();
}
}

我的计算机上的输出

mainthreadentered A.foo

racingthreadentered B.bar

mainthreadtrying to call B.last()

racingthreadtrying to call A.last()

4 个答案:

答案 0 :(得分:5)

你有一个经典的僵局。

  • A.foo()锁定a并调用试图锁定b.last()的{​​{1}}
  • b锁定B.bar()并调用试图锁定b1的{​​{1}}

两者都不能继续,因为每个人都需要锁定另一个。

  

我不知道为什么线程处于死锁状态。

因为这是您的计划的目的。


鉴于您不需要任何锁定,最简单的解决方案是删除所有a.last()个关键字。

答案 1 :(得分:0)

由于对象b在bar()a foo()上被锁定,因此当您调用last()时,每个函数都在等待另一个函数释放锁定。这导致死锁

答案 2 :(得分:0)

看起来像家庭作业。但我会说答案是你在deadlock()的构造函数中设置另一个线程的事实。

两个线程都会竞争,并且可能会锁定其中一个同步方法,因为您正在使用计时器将它们排成一行。是我的猜测没有运行它。

类名也应该是大写的。

答案 3 :(得分:0)

Deadlock没有解决方案。程序员必须注意并以不会发生死锁的方式进行编码。