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());
System.out.println("Nice try " + this.name);
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();
}
}
让我们看看一些真实的例子
run:
Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed to me!
Nice try Gaston
Nice try Alphonse
所以Alphonse和Gaston,现在正在运行“bow()”,每个人在“bow()”的末尾试图互相调用“bowBack()”,“bowBack()”并不是静止的,因此Alphonse和Gaston已经分离了这个方法的实例,之前也没有调用“bowBack()”,因此它不应该被阻塞。那么为什么这是一个僵局。
在教程中 http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
它被解释为
When Deadlock runs, it's extremely likely that both threads will block when they
attempt to invoke bowBack. Neither block will ever end, because each thread is
waiting for the other to exit bow.
但是为什么要运行“bowBack()”它应该先等待“bow()”的结束,如果它们不互相干扰
Alphonse.bow()--->试图打电话 - > Gaston.bowBack()
Gaston.bow()--->试图调用 - > Alphonse.bowBack()
答案 0 :(得分:2)
但是为什么要运行“bowBack()”它应该先等待“bow()”的结束,如果它们不互相干扰
调用bowBack()
时 - 正在运行的线程尝试获取的锁定是Object
锁定其尝试调用的方法。
这里 - Alphonse是一个对象,Gaston是第二个对象。
Alphonse.bow()--->试图打电话 - > Gaston.bowBack()
在上面,第一次调用锁定了Alphonse,当仍然保持锁定时,尝试锁定Gaston。
因此,在线程1:锁定(Alp)并尝试锁定(加斯顿)而不释放锁定(Apl)
Gaston.bow()--->试图调用 - > Alphonse.bowBack()
在这里,第一个bow()获取对Gaston对象的锁定,然后尝试获取对Alphonse的锁定。
所以,在线程2:锁定(加斯顿)并尝试锁定(Apl)而不释放锁定(加斯顿)
如果线程1和线程2中的第一步都完成了,那么你可以看出第二步永远无法完成 - 因此死锁