我从甲骨文那里得到了这个死锁示例代码。
class Thread_Test {
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();
}
}
如果我像下面这样改变函数弓,我可以解决死锁问题。
public void bow(Friend bower) {
synchronized(this) {
System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName());
}
bower.bowBack(this);
}
我能用其他方法来解决这个死锁问题吗?
特别是,我想知道thread.sleep()可以解决死锁问题,以及如何使用它。
你能告诉我thread.sleep()和其他方法的可能性吗?
多谢
最佳答案
发生死锁是因为发生了以下方法调用:
alphonse calls bow(),获取alphonse/bow锁
Gaston调用bow(),获取Gaston/bow锁
阿尔方斯让加斯顿退后(),并等待加斯顿完成该动作。
加斯顿让阿尔方斯向后鞠躬(),并等待阿尔方斯完成该动作。
因此,双方都在等待对方完成弓背(),以便完成他们的弓背(),但在他们完成弓背()之前无法开始他们自己的弓背。僵局。
解决方案有效的原因是bowback(this)调用不在synchronized块内。
聪明地使用锁可以更清楚地说明死锁发生的原因和确切位置,并可以防止死锁发生。java的信号量类是一个很好的研究对象。
要实际修复它(防止死锁,但保持线程安全),您必须扩展问题-当Gaston等待Alphonse完成bow()以执行自己的bow()时,会发生什么情况,但Alphonse需要Gason执行bowback()以完成?一个明智的解决方案是,gaston在调用bowback()时放弃执行bow(),而只执行bowback(),但这都取决于您试图解决的问题。