Concurrency 下面的代码中死锁是如何发生的?
我试图从Oracle的网站上了解死锁,但不确定两个自定义线程何时进入死锁状态Concurrency 下面的代码中死锁是如何发生的?,concurrency,deadlock,Concurrency,Deadlock,我试图从Oracle的网站上了解死锁,但不确定两个自定义线程何时进入死锁状态 package com.geekthread.java.threads; public class DeadLock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() {
package com.geekthread.java.threads;
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");
//holds lock for alphonse
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
//holds lock for gastone
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
}
请纠正我对上述计划的理解:- 1.)持有阿尔方斯的锁
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
2.)为加斯通持有锁
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
我尝试从bowback中删除synchronized关键字,该关键字不会在死锁情况下结束,即程序执行完成,程序在执行后终止
谢谢我肯定不是Java方面的专家,但我的猜测是: 由于类友元是静态的,因此类友元的方法是静态的。因此,这些方法锁定类本身,而不是类的对象
这将提供更多的细节:每个对象都有一个与其关联的锁,也称为隐式锁或监视器锁。当
synchronized
用于示例中的方法时,线程将尝试获取与该方法的对象关联的锁。因此,运行alphonse.bow(加斯顿)的线程代码>将获取与alphonse对象关联的锁
大致在同一时间,运行gaston.bow(阿尔方斯)的线程
将获取与gaston对象关联的锁
所以你有阿尔方斯线程持有阿尔方斯对象的锁,加斯顿线程持有加斯顿对象的锁
当alphonse现在尝试执行bower.bowBack(这个)代码>,请注意,“bower”指的是gaston对象。因此,alphonse正在尝试执行gaston对象的bowBack
方法。由于bowBack方法是同步的,alphonse需要获得gaston对象锁才能继续。但是当然gaston线程已经有了gaston对象锁
因此,alphonse正在尝试执行gaston的bowBack方法,但无法执行,因为它无法获得gaston对象锁
与此同时,加斯顿也有同样的问题。他需要调用alphonse的bowBack方法,但是alphonse线程已经有了alphonse对象锁
因此,每个线程都有一个锁,并试图获得另一个线程已经拥有的锁,而这两个线程都无法继续-这是一个典型的死锁场景
编辑:从bowBack
中删除“synchronized”可以防止死锁,正如您所发现的,因为现在没有任何东西可以阻止alphonse线程调用gaston的bowBack
方法-alphonse不再需要获得gaston持有的gaston对象锁。同样的逻辑反过来适用于gaston,gaston也可以继续。这是错误的:“因为类友元是静态的,类友元的方法是静态的”类是静态的,因此我们可以在同一个文件中有多个类。如果Friend
在它自己的Friend.java
文件中,而不是static@dkatzel谢谢不知道java的静态类概念。