Java死锁代码说明

sol*_*4me 4 java multithreading

有人可以解释为什么以下代码导致死锁.我的理解是,当alphonse(线程)运行然后它获取对朋友obj的锁定,因为它调用bow()方法但是gaston(另一个线程)如何能够在alphonse尚未完成时获取同一朋友obj上的锁定/释放朋友obj的锁定.

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.println("invoked by " + name);
        System.out.format("%s: %s"
            + "  has bowed to me!%n", 
            this.name, bower.getName());
        bower.bowBack(this);
        System.out.printf("finished by " + name);
    }
    public synchronized void bowBack(Friend bower) {
        System.out.format("%s: %s"
            + " has bowed back to me!%n",
            this.name, bower.getName());
        System.out.println("exiting bowBack()");
    }
}

public static void main(String[] args) throws InterruptedException {
    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();
}
Run Code Online (Sandbox Code Playgroud)

}

JB *_*zet 6

  1. 线程1 : alphonse.bow(). 要输入此方法,线程1将获取alphonse的锁定,因为该bow()方法已同步.
  2. 线程2 : gaston.bow(). 要输入此方法,线程2获取gaston的锁,因为该bow()方法是同步的.
  3. 线程1 : gaston.bowBack(). 要输入此方法,线程1需要获取gaston的锁,因为该bowBack()方法是同步的.它一直等到线程2释放了gaston锁
  4. 线程2 : alphonse.bowBack(). 要输入此方法,线程2需要获取alphonse的锁,因为该bowBack()方法是同步的.它一直等到线程1释放了alphonse锁

两个线程最终等待彼此.这是一个僵局.