为什么java僵局在这里?

时间:2013-09-04 20:51:59

标签: 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();
    }
}

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

这是一个导致僵局的场景:

  • 线程1调用alphonse.bow(),从而获得alphonse的锁
  • 线程2调用gaston.bow(),从而获得gaston的锁定
  • 线程1想要调用gaston.bowBack(),但阻止直到gaston的锁被释放
  • 线程2想要调用alphonse.bowBack(),但阻止alphonse的锁被释放

所以两个线程无限地等待彼此。