首页 > 解决方案 > Java 官方死锁示例

问题描述

我从Oracle官方网站阅读了教程并看到了这个例子

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) throws Exception{
        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();
    }
}

我不明白为什么会发生死锁?据我了解,线程 alphonse 执行完成然后释放锁,然后线程 gaston 将继续执行,没有死锁。

标签: java

解决方案


你应该运行它看看。它永远不会退出。

当你得到一个线程转储时,你会看到两个线程:

"Thread-0" #14 prio=5 os_prio=31 cpu=16.42ms elapsed=8.92s tid=0x00007fb3e6000000 nid=0x6603 waiting for monitor entry  [0x0000700004ef3000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at Deadlock$Friend.bowBack(Deadlock.java:17)
    - waiting to lock <0x000000061fff4b78> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:14)
    - locked <0x000000061fff4b38> (a Deadlock$Friend)
    at Deadlock$1.run(Deadlock.java:29)
    at java.lang.Thread.run(java.base@15-ea/Thread.java:832)

"Thread-1" #15 prio=5 os_prio=31 cpu=0.71ms elapsed=8.92s tid=0x00007fb3e587ee00 nid=0x8e03 waiting for monitor entry  [0x0000700004ff6000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at Deadlock$Friend.bowBack(Deadlock.java:17)
    - waiting to lock <0x000000061fff4b38> (a Deadlock$Friend)
    at Deadlock$Friend.bow(Deadlock.java:14)
    - locked <0x000000061fff4b78> (a Deadlock$Friend)
    at Deadlock$2.run(Deadlock.java:35)
    at java.lang.Thread.run(java.base@15-ea/Thread.java:832)

查看每个已锁定并正在等待的监视器的 ID。

您可以看到第一个线程正在等待第二个线程持有的锁,反之亦然。


推荐阅读