Java 为什么死锁不是';怎么回事?

Java 为什么死锁不是';怎么回事?,java,multithreading,deadlock,Java,Multithreading,Deadlock,我对僵局的行为感到困惑。 如果我先在死锁类的构造函数中编写a.foo(b),然后编写t.start(),那么死锁不会发生,但为什么呢 class A { synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entered A.foo"); try { Thre

我对僵局的行为感到困惑。 如果我先在死锁类的构造函数中编写
a.foo(b)
,然后编写
t.start()
,那么死锁不会发生,但为什么呢

class A {

    synchronized void foo(B b) {
        String name = Thread.currentThread().getName();
        System.out.println(name + " entered A.foo");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            System.out.println("A Interrupted");
        }
        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 B.last");
    }
}


public class Deadlock implements Runnable {

    A a = new A();
    B b = new B();
    Thread t;

    Deadlock() {
        Thread.currentThread().setName("MainThread");
        t = new Thread(this, "RacingThread");
        a.foo(b);
        t.start();

    }

    public static void main(String args[]) {
        new Deadlock();
    }

    public void run() {
        b.bar(a);
    }
}

要产生死锁,必须有两个进程(
a
b
)和两个锁(
x
y
)。他们必须按照如下顺序获取锁:

  • a
    获取
    x
  • b
    获取
    y
  • a
    正在等待获取
    y
  • b
    正在等待获取
    x
在代码中,有
同步的
方法。他们正在获取与方法运行的实例关联的锁。也就是说,他们从不试图获得对方的锁。这就是它们被序列化的原因


要产生死锁,您需要依赖于
synchronized
方法的隐式锁以外的其他锁。

要产生死锁,您必须有两个进程(
a
b
)和两个锁(
x
y
)。他们必须按照如下顺序获取锁:

  • a
    获取
    x
  • b
    获取
    y
  • a
    正在等待获取
    y
  • b
    正在等待获取
    x
在代码中,有
同步的
方法。他们正在获取与方法运行的实例关联的锁。也就是说,他们从不试图获得对方的锁。这就是它们被序列化的原因


要产生死锁,您需要依赖于
synchronized
方法的隐式锁以外的其他锁

如果我先在类的构造函数
Deadlock
中编写
a.foo(b)
,然后编写
t.start()

class A {

    synchronized void foo(B b) {
        String name = Thread.currentThread().getName();
        System.out.println(name + " entered A.foo");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            System.out.println("A Interrupted");
        }
        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 B.last");
    }
}


public class Deadlock implements Runnable {

    A a = new A();
    B b = new B();
    Thread t;

    Deadlock() {
        Thread.currentThread().setName("MainThread");
        t = new Thread(this, "RacingThread");
        a.foo(b);
        t.start();

    }

    public static void main(String args[]) {
        new Deadlock();
    }

    public void run() {
        b.bar(a);
    }
}
这是因为对
a.foo(b)
的调用不是异步的,因此在对
a.foo(b)
的调用完成之前不会调用
t.start()

如果我先在类的构造函数
Deadlock
中编写
a.foo(b)
,然后编写
t.start()

class A {

    synchronized void foo(B b) {
        String name = Thread.currentThread().getName();
        System.out.println(name + " entered A.foo");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            System.out.println("A Interrupted");
        }
        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 B.last");
    }
}


public class Deadlock implements Runnable {

    A a = new A();
    B b = new B();
    Thread t;

    Deadlock() {
        Thread.currentThread().setName("MainThread");
        t = new Thread(this, "RacingThread");
        a.foo(b);
        t.start();

    }

    public static void main(String args[]) {
        new Deadlock();
    }

    public void run() {
        b.bar(a);
    }
}

这是因为对
a.foo(b)
的调用完成后才会调用
t.start()
,因为对
a.foo(b)
的调用不是异步的。

运行此程序时,创建的第一个线程是'main thread',因此如果在t.start()之前调用a.foo(b)),该程序将由主线程串行执行。因此,在主线程下,直到a.foo()->b.foo()的执行堆栈结束t.start()才会执行,即

以简单的方式执行,直到第4行的代码在 行号5将不被执行


。因此在
a.foo(b)的情况下;t、 开始死锁是不可能的。但在
t.start()的情况下;a、 傅(乙);异步执行将在'thread t.start()'之后不久开始,因此它会导致两个线程之间出现死锁,试图访问彼此相反的锁。

运行此程序时,创建的第一个线程是'main thread',因此如果在t.start()之前调用a.foo(b),则,该程序将由主线程串行执行。因此,在主线程下,直到a.foo()->b.foo()的执行堆栈结束t.start()才会执行,即

以简单的方式执行,直到第4行的代码在 行号5将不被执行


。因此在
a.foo(b)的情况下;t、 开始死锁是不可能的。但在
t.start()的情况下;a、 傅(乙);异步执行将在'thread t.start()'之后很快开始,因此它会导致两个线程之间的死锁,试图访问彼此相反的锁。

您能解释一下您认为这里发生了什么会导致死锁吗?这看起来很好…你的std输出是什么?你能解释一下你认为这里发生了什么会导致死锁吗?这看起来很好…你的性病输出是什么?谢谢。我已经解决了问题。谢谢。我已经解决了问题。