这个java代码是如何产生死锁的?
我正在查看oracle文档以查找死锁。。 我找到了这个密码这个java代码是如何产生死锁的?,java,multithreading,deadlock,Java,Multithreading,Deadlock,我正在查看oracle文档以查找死锁。。 我找到了这个密码 public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.
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();
}
}
我不明白,在什么情况下会出现僵局
我运行这段代码,它运行得很好。所以一定有一些特殊的事件,什么时候会发生死锁
假设先在alphonse
对象上调用bow,当bower.bowBack(此)
在bower对象上调用时,它是否会在alphonse
对象上保持锁定?
因为如果它保留了锁,bow
函数在另一个对象上不会得到锁,直到alphonse
离开它的锁,并且永远不会出现死锁情况。如果你放一个线程。sleep(1000)在打印第一行之后,在调用bowBack之前,你应该会看到死锁。这种僵局可能会发生,这将是罕见的
您有两个线程和两个锁被获取是不同的顺序。这会使每个线程持有一个锁,但无法获得第二个锁。i、 僵局
注意:线程启动需要很多时间,这意味着第一个线程可以在第二个线程启动之前运行到完成,因此您不太可能看到问题
这是给你的拼图游戏。这会造成死锁,你知道为什么吗
class A {
static final int i;
static {
i = 128;
Thread t = new Thread() {
public void run() {
System.out.println("i=" + i);
}
};
t.start();
try {
t.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
在处理多线程时,两个线程中的操作可能以任何顺序发生。所以想象一下,在这种情况下,两个参与者都执行
bow
,然后他们都尝试执行bow\u back
。由于bow
和bow\u back
处于同步状态,两个对象都将被锁定,您将无法对其中任何一个对象执行bow\u back
。两个对象都将等待,直到另一个对象“自由”,这不会发生,因为弓在“向后弓”之前不会返回。在弓A和G的末尾调用bowBack,导致A调用G.bow,G调用A.bow,而A和G的弓是同步的。所以它们都在等待对方完成。你有两个对象,阿尔方斯和加斯顿,还有两个线程,线程1和线程2
假设发生这种情况:
Thread1:alphonse进入bow()方法。并将锁定阿尔方斯物体
Thread2:gaston进入bow()方法。并将在加斯顿物体上保持一把锁
Thread1:alphonse在bow()方法中调用gaston对象上的bowBack()
->Thread1将阻塞,因为Thread2已锁定gaston
Thread2:gaston在bow()方法中调用alphonse对象上的bowBack()
->Thread2将被阻止,因为Thread1已经锁定了alphonse
现在Thread1正在等待Thread2。Thread2正在等待Thread1。这是一个死锁。如果双方同时进入bow()
方法,或者在
System.out.println();
如果您没有看到这两条“已向我鞠躬!”消息,则会发生死锁
如果第一个线程在第二个线程启动之前终止,则不会出现死锁
使用Thread.sleep(1000)扩展代码
然后两个线程都进入bow()并解除锁定。您认为它运行良好是什么意思,请发布输出,可能您认为它运行良好,这就是死锁!“向我鞠躬”的信息在哪里?对不起,有时它会给阿尔方斯:加斯顿向我鞠躬了!加斯顿:阿尔方斯向我鞠躬了!加斯顿:阿尔方斯向我鞠躬了!阿尔方斯:加斯顿向我鞠躬了!有时阿尔方斯:加斯顿向我鞠躬了!加斯顿:阿尔方斯向我鞠躬了@是的,你是对的,有时是死锁,有时是不可能复制的,我看没有问题,除了这一行Thread.currentThread().interrupt();在接球区?但我不明白有人能解释这个问题吗?或者我想我将不得不把它作为另一个问题发布,因为现在它让我好奇地想知道答案?类和静态块的加载是隐式的同步的
,这意味着在初始化一个类时,你不能在另一个线程中访问该类中的任何内容。在这种情况下,初始化正在等待使用a.i
的线程,即等待第一个线程完成静态块。
public synchronized void bow(Friend bower) {
System.out.println(....);
Thread.sleep(1000);
...
}