Java 中同步方法的死锁

k13*_*13i 2 java concurrency multithreading deadlock

此代码来自有关并发的Oracle 教程。我不明白为什么同步方法会导致deadlock. 当方法不是synchronized一切正常时,但是当我添加synchronized关键字时,程序停止并且bowBack()从不调用方法。有人可以以负担得起的方式解释为什么会发生这种情况吗?下面是提到的代码片段:

public class Deadlock {
    static class Friend {
        private final String name;

        Friend(String name) {
            this.name = name;
        }

        String getName() {
            return this.name;
        }

        synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                        + "  has bowed to me!%n",
                this.name, bower.getName());
            bower.bowBack(this);
        }

        synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                        + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(() -> alphonse.bow(gaston)).start();
        new Thread(() -> gaston.bow(alphonse)).start();
    }
}
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 5

  • 线程 1: alphonse.bow(gaston) -> 线程 1 持有 alphonse 的锁,因为 bow() 是同步的
  • 线程 2 : gaston.bow(alphonse) -> 线程 2 持有 gaston 的锁,因为 bow() 是同步的
  • 线程 1 : gaston.bowBack(alphonse) -> 阻塞,因为 bowBack 是同步的,因此线程 1 需要获取线程 2 已经持有的 gaston 锁
  • 线程 2 : alphonse.bowBack(gaston) -> 阻塞,因为 bowBack 是同步的,因此线程 2 需要获取线程 1 已经持有的 alphonse 的锁

所以两个线程都被阻塞,等待另一个释放锁。