英文:
How to check deadlock in this example
问题
目前我正在学习死锁,并且我找到了一个死锁的例子,但我不明白在这个例子中是如何发生死锁的。
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!
或者我可能对这里的同步机制有误解。
英文:
currently I am learning deadlock and I found a example of deadlock but I don't get how deadlock is occurring in this example.
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());
}
}
}
I spend more then one hour understanding how things are happening here but didn't got it.
here is the output which I am getting
Jane: John has said hello to me!
John: Jane has said hello to me!
or maybe I misunderstood synchronisation here.
答案1
得分: 0
一个使用 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 释放锁,反之亦然。
-
死锁。
英文:
A method marked with synchronized
locks the critical-section (the method) using this
as the lock. To enter a critical section (and lock it), a thread needs to acquire the corresponding lock. If the section is already locked, the thread is blocked at the entrance and waits for the lock to be released.
A and B are threads:
- A calls
jane.sayHello(john)
and locksjane
. - B calls
john.sayHello(jane)
and locksjohn
.
Notice that sayHello
is marked with synchronized
.
- A calls
person.sayHelloBack(this)
, whereperson
isjohn
. - B calls
person.sayHelloBack(this)
, whereperson
isjane
.
Notice that sayHelloBack
is also marked with synchronized
.
-
B holds
john
, so A's calljohn.sayHelloBack
is blocked. -
A holds
jane
, so B's calljane.sayHelloBack
is blocked. -
A is waiting for B to release the lock and vice versa.
-
Deadlock.
答案2
得分: 0
当我们将一个方法标记为synchronized
时,它会在当前对象上获取一个锁。因此,第一个线程在对象jane
上获取锁,而第二个线程在调用方法sayHello()
时会在对象john
上获取锁。
由于您还将sayHelloBack()
标记为synchronized
,它将等待直到另一个线程释放调用对象上的锁。对于第一个线程,它调用john.sayHelloBack()
,试图在john
上获取锁 - 但该锁已经被thread-2
获取。对于第二个线程,它调用jane.sayHellpBack()
,试图在jane
上获取锁 - 但该锁已经被thread-1
获取。
因此,两个线程都在那一点上等待锁,导致了死锁。
英文:
When we mark a method as synchronized
, it takes a lock on the current object. So, the first thread takes a lock on the object jane
whereas the second thread takes lock on the object john
, as soon as it calls the method sayHello()
.
As you have marked the sayHelloBack()
also as synchronized, it would wait until the other thread releases lock on the invoking object. For the first thread, it calls john.sayHelloBack()
, it tries to acquire lock on john
- but it has already been acquired by thread-2
. For the second thread, it calls jane.sayHellpBack()
, it tries to acquire lock on jane
- but it is already acquired by thread-1
.
So, both the threads keep waiting for the lock at that point causing the deadlock.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论