以下代码段取自Java Tutorials,表示线程永远被阻止,但我无法弄清楚如何。请解释一下。
这两个同步方法是否共享同一个内部锁?
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();
}
}
答案 0 :(得分:3)
在上面的示例中,可能存在以下情况:
alphonse has his own lock
gaston has his own lock
因为在自己的线程中使用自己的锁调用bow()
方法。如果你仔细看,在bow()
方法中,alphonse现在使用另一个引用调用bowback()
,即使用gaston的锁。
所以,可能有一种情况,gaston已经使用他自己的锁进入bow()
方法,但是alphonse的线程试图输入已经被gaston的线程锁定的bowback()
方法。反之亦然。
因此,调用bowback()
方法的引用的反转是容易出错的,这可能会导致死锁。
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this); // <--------- This Line
// here bower is not the same person how acquired
// the lock while calling bow() method
}
答案 1 :(得分:0)
是的,这两种方法都有相同的锁(我猜对象本身),因为它们表示here:
当一个线程正在为对象执行同步方法时,全部 调用同一对象的同步方法的其他线程 块
答案 2 :(得分:0)
在一个Thread中,来自方法bow的上下文在其他Thread的上下文中被称为方法,这就是问题。
对于Alphonse和Gaston来说,这个对象是不同的,并且在两个线程中依次对这两个线程进行同步。进入的第一个线程将进行第一次锁定并尝试获取第二个,但是由于其他线程被其他线程占用,它将被停止。
如果一个Thread等待其他人完成完整计算,则不会出现问题。
答案 3 :(得分:0)
线程A在bow(gaston)
时获取alphonse锁
线程B在bow(aphonse)
时获取gaston锁
线程A在bowBack(gaston)
时等待锁定
线程B在bowBack(aphonse)
答案 4 :(得分:0)
从您的链接:
当死锁运行时,两个线程在尝试时都很可能会阻塞 调用bowBack。这两个块都不会结束,因为每个线程都在等待另一个线程退出弓。
什么是死锁?
通常,当线程(1)锁定资源(A)然后尝试锁定另一个资源(B)时会发生死锁,但资源B被锁定从另一个尝试锁定资源A的线程(2)。
在这种情况下,没有线程可以访问这两个资源,并且会一直等到资源空闲。
无论如何,杰米注意到如果你运气好的话就不会发生僵局,但是有了i7我会得到这个
Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed to me!
请记住方法中的synchronized
表示synchronized(this)
。
@Nikita Rybak回答同一个问题(Java deadlock question)(赞成他的回答!)
其他答案: