我正在学习Java的死锁,并且有来自Sun官方教程的以下示例代码:
Alphonse and Gaston are friends, and great believers in courtesy. A strict rule of courtesy is that when you bow to a friend, you must remain bowed until your friend has a chance to return the bow. Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time.
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();
}
}
这是Sun的解释:
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.
我似乎不太了解。当alphonse.bow(gaston)运行时,bow方法被锁定。因此,现在它将首先打印“Gaston向我鞠躬!”。然后它将继续并调用bowBack,并同时锁定bowBack。这怎么会造成僵局?我是否误解了调用同步方法时会发生什么?
如果有人可以给我一个简单的解释,谢谢。
最佳答案
需要注意的重要一点是,锁定的不是方法而是对象实例。
当您调用alphonse.bow(gaston)
时,它将尝试获取对alphonse
的锁定。拥有锁后,它将打印一条消息,然后调用gaston.bowBack(alphonse)
。此时,它尝试获取对gaston
的锁定。一旦获得了锁,它将打印一条消息,然后释放该锁,最后释放alphonse
上的锁。
在死锁中,锁的获取顺序使得任何一个线程都无法继续执行。
alphonse
的锁定gaston
的锁定gaston
的锁-不能,因为线程2已经拥有它。 alphonse
的锁定-不能,因为线程1已经拥有它。 关于java - 有关Java死锁情况的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35299310/