好。我在理解并发基础方面遇到一些困难。这个问题是关于死锁的。请告诉我为什么这两个线程都以死锁结尾。
我从this教程中获得了此示例。它说,
“当死锁运行时,两个线程极有可能在尝试调用bowBack时阻塞。任何一个阻塞都不会结束,因为每个线程都在等待另一个退出bow。”
我从中了解到的是:第一,它们会等待,因为当线程调用同步方法时,它会自动获取该同步方法所属的对象的固有锁,并继续拥有该对象,直到该方法返回为止。同时没有其他线程可以拥有它。
现在,我的第一个问题是第一个线程调用zarah.bow(),因此固有锁定与zarah相关联。第二个线程将调用khan.bow(),因此它将是一个不同的内在锁(因为它与名为khan的另一个对象相关联),不是吗?
zarah.bow()和khan.bow()是否不同?因为它们属于两个不同的实例?
第二个问题来自线程“永远等待”的概念。这两个线程将永远被阻塞,以等待彼此退出弓。我不明白
package Threads;
public class DeadlockModified {
static class Friend {
private final String name;
Friend(String name){
this.name=name;
}
private String getName(){
return this.name;
}
private synchronized void bow(Friend bower){
System.out.format("%s: %s"+" bowed to me.%n",bower.getName(),name);
bower.bowBack(this);
}
private synchronized void bowBack(Friend bower){
System.out.format("%s: %s" + " was nice enough to bow back to me.%n",bower.getName() ,name );
}
}
public static void main(String [] args){
final Friend zarah= new Friend("Zarah");
final Friend khan= new Friend("Khan");
new Thread(new Runnable(){
public void run(){zarah.bow(khan);}
}).start();
new Thread(new Runnable() {
public void run(){khan.bow(zarah);}
}).start();
}
}
输出:-
Khan: Zarah bowed to me.
Zarah: Khan bowed to me.
先感谢您。
编辑:-
在本教程的“同步方法”部分中,写道:
“从同步代码中调用其他对象的方法可能会导致问题,有关生动性的部分将对此进行介绍。”
这是关于活力的部分。我看到从bow()调用了另一个对象的方法bowBack()。还有一些问题-查看程序的输出,看起来两个线程都未执行bowBack()。但是没有更多细节。
最佳答案
线程1调用zarah.bow(khan)
:它获取zarah
引用的对象的内部锁
线程2调用khan.bow(zarah)
:它获取khan
引用的对象的固有锁定。
线程1尝试调用khan.bowBack()
:它需要khan的固有锁定才能执行此操作。但是此锁由线程2持有。因此线程1等待,直到线程1释放khan
的锁为止。
线程2尝试调用zarah.bowBack()
:它需要zarah的内在锁才能做到这一点。但是此锁由线程1持有。因此,线程2等待直到线程1释放zarah
的锁。
因此,两个线程永远都在等待对方。那是一个僵局。