在java教程中,我看到了这个简单的死锁示例,并且由于某种原因无法弄清楚它为什么被阻止
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()
最佳答案
but why, to run "bowBack()" it should first wait the end of the "bow()", if they don't interfere with each other
当调用 bowBack()
时 - 正在运行的线程尝试获取的锁是它尝试调用其方法的 Object
上的锁。
这里 - Alphonse 是一个对象,Gaston 是第二个对象。
Alphonse.bow()--->尝试调用-->Gaston.bowBack()
在上面,第一个调用锁定了 Alphonse,并在该锁定仍保持的同时尝试获取 Gaston 的锁定。
因此,在线程 1 中:锁定 (Alp) 并尝试锁定(Gaston),而不释放锁定(Apl)
Gaston.bow()--->尝试调用-->Alphonse.bowBack()
在这里,第一个 Bow() 获取 Gaston 对象上的锁,然后尝试获取 Alphonse 上的锁。
因此,在线程 2 中:锁定 (Gaston) 并尝试锁定(Apl),而不释放锁定(Gaston)
如果线程 1 和线程 2 中的第一步都已完成,那么您可以算出第二步永远无法完成 - 因此出现死锁
关于java - 多线程死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24580686/