gpt4 book ai didi

java - 多线程死锁

转载 作者:行者123 更新时间:2023-12-02 05:40:16 24 4
gpt4 key购买 nike

在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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com