0

我有一个来自 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();
    }
}
4

2 回答 2

3

取决于时间。每个线程进入弓,并将该对象锁定到该线程。然后,在该同步方法中,它尝试在另一个对象上调用 bowBack。但是该方法是同步的,并且对象被锁定到另一个线程。所以两个线程都坐在那里等待另一个对象监视器释放,这永远不会发生。因此,陷入僵局。

同样,这真的取决于时间。如果第一个线程在第二个线程开始之前完成,它将正常工作。

于 2013-09-04T20:57:29.533 回答
3

这是导致死锁的场景:

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

所以两个线程都无限等待对方。

于 2013-09-04T20:59:19.153 回答