目前我正在学习死锁,我发现了一个死锁的例子,但我不知道死锁是如何在这个例子中发生的。
public class Main {
public static void main(String[] args) {
final PolitePerson jane = new PolitePerson("Jane");
final PolitePerson john = new PolitePerson("John");
new Thread(new Runnable() {
@Override
public void run() {
jane.sayHello(john);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
john.sayHello(jane);
}
}).start();
}
static class PolitePerson {
private final String name;
public PolitePerson(String name) {
this.name = name;
}
public String getName() {
return name;
}
public synchronized void sayHello(PolitePerson person){
System.out.format("%s: %s" + " has said hello to me!%n", this.name, person.getName());
person.sayHelloBack(this);
}
public synchronized void sayHelloBack(PolitePerson person) {
System.out.format("%s: %s" + " has said hello back to me!%n", this.name, person.getName());
}
}
}
我花了一个多小时来了解这里的情况,但没有明白。这是我得到的输出
Jane: John has said hello to me!
John: Jane has said hello to me!
或者我误解了同步。
2条答案
按热度按时间ddrv8njm1#
当我们将一个方法标记为
synchronized
,它将锁定当前对象。因此,第一个线程锁定对象jane
而第二个线程锁定对象john
,只要它调用方法sayHello()
.正如你所标记的
sayHelloBack()
同样是同步的,它将等待另一个线程释放调用对象上的锁。对于第一个线程,它调用john.sayHelloBack()
,它试图获得锁定john
-但它已经被thread-2
. 对于第二个线程,它调用jane.sayHellpBack()
,它试图获得锁定jane
-但它已经被thread-1
.因此,两个线程都在等待导致死锁的锁。
nzrxty8p2#
有标记的方法
synchronized
使用锁定关键部分(方法)this
就像锁一样。要进入一个关键部分(并锁定它),线程需要获得相应的锁。如果节已经被锁定,线程将在入口被阻塞,并等待锁被释放。a和b是螺纹:
a电话
jane.sayHello(john)
和锁jane
.b电话
john.sayHello(jane)
和锁john
.注意
sayHello
标记为synchronized
.a电话
person.sayHelloBack(this)
,在哪里person
是john
.b电话
person.sayHelloBack(this)
,在哪里person
是jane
.注意
sayHelloBack
也标记为synchronized
.b保持
john
,所以a的电话john.sayHelloBack
已阻止。a保持
jane
所以b的电话jane.sayHelloBack
已阻止。a正在等待b释放锁,反之亦然。
僵局。