Dad*_*box 15 java multithreading deadlock
首先,这是一个示例:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我没有得到的是阻塞是如何发生的.main函数启动两个线程,每个线程都开始自己的弓箭.
究竟什么'同步'阻止?为同一个对象运行相同的函数(我原来认为)?同一个类的所有对象的相同功能?同一对象的所有同步函数?同一类的所有对象的所有同步函数?
帮帮我吧
Edd*_*die 26
在Java中,每个都Object提供了线程对其进行synchronize或锁定的能力.方法同步时,该方法使用其对象实例作为锁.在您的示例中,方法bow和bowBack都是synchronized,并且两者都在同一个类中Friend.这意味着执行这些方法的任何线程将在Friend实例上作为其锁定进行同步.
导致死锁的一系列事件是:
alphonse.bow(gaston),这是synchronized在上alphonse Friend对象.这意味着Thread必须从该对象获取锁.gaston.bow(alphonse),这是synchronized在上gaston Friend对象.这意味着Thread必须从该对象获取锁.bowback并等待锁定gaston被释放.bowback并等待锁定alphonse被释放.要更详细地显示事件序列:
main()开始在主要的Therad中执行(称之为Thread#1),创建两个Friend实例.到现在为止还挺好.new Thread(new Runnable() { ....线程#2调用alphonse.bow(gaston),synchronized在alphonse Friend对象上.因此,线程#2获取alphonse对象的"锁定" 并进入该bow方法.gaston.bow(alphonse),在gaston Friend对象上同步.由于没有人获得gaston对象实例的"锁定",因此线程#3成功获取此锁并输入该bow方法.bower.bowBack(this);,bower作为对实例的引用gaston.这是调用的逻辑等价物gaston.bowBack(alphonse).因此,这种方法就是synchronized在gaston实例上.此对象的锁已被获取并由另一个线程(线程#3)保持.因此,线程#2必须等待锁定gaston被释放.线程处于等待状态,允许线程#3进一步执行.bowback,在这种情况下,它在逻辑上与调用相同alphonse.bowBack(gaston).为此,它需要获取alphonse实例的锁,但此锁由Thread#2保存.此线程现在处于等待状态.而且你现在处于两个Thread都不能执行的位置.线程#2和线程#3都在等待锁定被释放.但是没有Thread可以在没有Thread进展的情况下释放锁.但是如果没有锁被释放,两个线程都无法取得进展.
因此:死锁!
死锁通常取决于发生的特定事件序列,这可能使得难以调试,因为它们很难再现.