请考虑以下事项:
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("\n%S: %S has bowed to me!" , this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("\n%S: %S has bowed back to me!", this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alf = new Friend("Alf");
final Friend arian = new Friend("Arian");
// Thread 1
new Thread(new Runnable() {
public void run(){ alf.bow(arian);}}).start();
//Thread 2
new Thread(new Runnable() {
public void run(){ arian.bow(alf);}}).start();
}
}
输出是
ALF:ARIAN向我鞠躬致敬! ARIAN:ALF向我鞠躬!
锁定状况.....
当线程1运行时,它需要锁定对象Friend。紧接着线程2需要锁定第二个对象。现在方法 bow 被线程1锁定,因此打印出“ALF:ARIAN向我鞠躬!”。线程2如何进入 bow ,两者都不能输入 * bowBack * ??
关心B.
答案 0 :(得分:5)
请注意,synchronized
方法始终会在this
上同步。
有两个对象,因此有两个锁。 alf.bow()
获取alf
锁,arian.bow()
获取arian
s。但是bowback()
试图获取另一个,即发生死锁时。
如果要在共享锁对象上进行同步,则应该执行以下操作:
class Friend {
private static final Object lock = new Object();
public void bow(...) {
synchronized( lock ) {
...
}
}
public void bowback(...) {
synchronized( lock ) {
...
}
}
}
由于lock
在静态字段中,这意味着Friend
的所有实例都使用相同的锁对象,因此不存在死锁的可能性。
您还可以在类对象synchronized( Friend.class ) {...}
上进行同步,但在外部可见对象上进行同步通常不是一个好主意,因为无法保证代码的其他部分不会窃取锁定。
答案 1 :(得分:3)
使用任何对象完成同步;如果线程与不同的对象同步,则它们可以同步进入同步块中。
实例方法中的synchronized
关键字表示该实例同步。由于您正在调用两个不同对象的bow
方法,因此无法同时执行此类函数。
通过类对象进行同步(或使用为此目的创建的静态最终对象)。
答案 2 :(得分:1)
- 您使用了2 objects
,这里的线程都使用了2个不同的Monitor锁。
- 由于两个线程都在锁定2 different object
,因此很明显,对象1上的线程1的锁定对线程2的锁定没有影响2。
- 您使用了synchronized
关键字,这需要对象锁定,并且您为两个线程提供了自己的对象锁,因此线程2进入船头。
答案 3 :(得分:1)
您需要锁定一个公共对象。
public static void main(String[] args) {
final Object lock = new Object();
final Friend alf = new Friend("Alf", lock);
final Friend arian = new Friend("Arian", lock);
...
}
public void bow(Friend bower){
synchronize(lock){
System.out.format("\n%S: %S has bowed to me!" , this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
synchronize(lock){
System.out.format("\n%S: %S has bowed back to me!", this.name, bower.getName());
}
}