在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因此,阿方斯和加斯顿现在都在运行"bowBack()“,在"bowBack()”的末尾试图在对方上调用"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()“,如果它们不相互干扰的话,应该先等待它们的结束。
Alphonse.bow()
Gaston.bow()
发布于 2014-07-04 21:10:14
但是为什么,要运行"bowBack()“,如果它们不相互干扰的话,应该先等待它们的结束。
当调用bowBack()时,正在运行的线程试图获取的锁是试图调用其方法的Object上的锁。
这里-阿方斯是一个物体,加斯顿是第二个物体。
Alphonse.bow()
在上面,第一次呼叫锁定了阿方斯,当这个锁仍然持有时,试图锁定加斯顿。
所以,在线程1:锁( Alp)中,尝试锁定( Gaston)而不释放锁(Apl)
Gaston.bow()
在这里,第一个蝴蝶结()在Gaston对象上锁定,然后尝试获取Alphonse上的锁。
所以,在线程2:锁(加斯顿)和尝试锁(Apl)不释放锁(加斯顿)
如果线程1和线程2中的第一步都完成了,那么您就可以计算出第二步永远无法完成,从而导致死锁。
https://stackoverflow.com/questions/24580686
复制相似问题