我正在尝试从Oracle的网站deadlock了解deadlock
,但不确定为什么&两个自定义线程何时进入死锁状态。
package com.geekthread.java.threads;
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");
//holds lock for alphonse
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
//holds lock for gastone
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
}
请更正我对上述计划的理解: -
1。)保持对alphonse的锁定
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
2。)保持对gastone的锁定
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
我试图从没有在死锁情况下结束的bowback中删除synchronized关键字,即程序执行完成,程序在执行后终止。
由于
答案 0 :(得分:2)
每个对象都有一个与之关联的锁,也称为隐式锁或监视器锁。当在示例中对方法使用synchronized
时,线程将尝试获取与该方法的对象关联的锁。因此,运行alphonse.bow(gaston);
的线程将获取与alphonse对象关联的锁。
大致在同一时间,运行gaston.bow(alphonse);
的线程将获取与gaston对象关联的锁。
所以你让alphonse线程持有alphonse对象的锁,而gaston线程持有gaston对象的锁。
当alphonse现在尝试执行bower.bowBack(this);
时,请注意'bower'是指gaston对象。因此alphonse正在尝试执行gaston对象的bowBack
方法。由于bowBack方法是同步的,因此alphonse需要使gaston对象锁定才能继续。但当然gaston线程已经有gaston对象锁定了!
所以alphonse试图执行gaston的bowBack方法,但不能因为它无法获得gaston对象的锁定。
与此同时,加斯顿也有同样的问题。他需要调用alphonse的bowBack方法,但是alphonse线程已经有了alphonse对象锁。
因此每个线程都有一个锁,并且正在尝试获取另一个线程已经拥有的锁,并且两者都无法继续 - 这是一个典型的死锁场景..
编辑:从bowBack
删除'synchronized'可以防止死锁,正如您所发现的那样,因为现在没有什么能阻止alphonse线程调用gaston的bowBack
方法 - alphonse不再需要获取gaston gaston持有的对象锁。相同的逻辑适用于gaston,他也可以继续。
答案 1 :(得分:0)
我绝对不是Java方面的专家,但我的猜测是:
由于类Friend是静态的,因此类Friend的方法是静态的。因此,这些方法锁定类本身而不是类的对象。
这应提供更多见解:8.4.3.6, 'synchronized Methods'