java - 为什么java会在这里死锁?

标签 java multithreading deadlock

我有一个来自 oracle.com 的例子,但我不明白。请解释一下。一根线程运行弓,然后它运行弓背,但为什么没有打印任何内容?

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            bower.bowBack(this);
        }
        public 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(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

最佳答案

这是导致死锁的场景:

  • 线程 1 调用 alphonse.bow() 并因此获得 alphonse 的锁
  • 线程 2 调用 gaston.bow() 并因此获得 Gaston 的锁
  • 线程 1 想要调用 gaston.bowBack(),但会阻塞,直到释放 Gaston 的锁
  • 线程 2 想要调用 alphonse.bowBack(),但会阻塞,直到 alphonse 的锁被释放

因此两个线程无限等待对方。

关于java - 为什么java会在这里死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18623554/

相关文章:

java - 在另一个 Synchronized 中调用 Synchronized

java - 无法突破 Ubuntu 16.04 内核 4.4.0 上的 12k 线程限制

java - SharedArray 死锁和引发条件

mysql - SELECT FOR UPDATE 和 INSERT ON DUPLICATE KEY UPDATE 导致 MYSQL 中同一行插入时出现死锁

java - GWT DateBox - 禁用特定日期

java - 如何使用 logback 关闭 STDOUT 形式的 Soap 消息 CXF

multithreading - 如何运行最大数量的 goroutine

mysql - 无法访问MYSQL中的某些表

java - 尝试了解 Servlet 调用的计数

java - 无法找到从 jsp 转换的 servlet(.java) 文件