5

考虑以下:

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:阿里安已经向我鞠躬了!阿里安:阿尔夫已经向我鞠躬了!

LOCK情况……

当线程 1 运行时,它需要锁定对象 Friend。紧接着线程 2 需要锁定第二个对象。现在方法bow 被线程 1 锁定,因此打印“ALF: ARIAN has bowed to me!”。线程 2 怎么进入bow也不能进入* bowBack * ??

问候 B。

4

4 回答 4

5

请记住,synchronized方法将始终在this.

有两个对象,因此有两个锁。alf.bow()获取alfs 锁并arian.bow()获取arians。但随后bowback()尝试获取另一个,这就是死锁发生的时候。

如果你想在共享锁对象上同步,你应该这样做:

class Friend {
   private static final Object lock = new Object();

   public void bow(...) {
     synchronized( lock ) {
        ...
     }
   }

   public void bowback(...) {
     synchronized( lock ) {
        ...
     }
   }

}

由于lock在静态字段中,这意味着所有实例都Friend使用相同的锁对象,因此不会出现死锁。

您也可以在类 object 上synchronized( Friend.class ) {...}同步,但在外部可见对象上同步通常不是一个好主意,因为无法保证代码的其他部分不会窃取锁。

于 2012-11-26T10:16:32.867 回答
3

使用任何对象进行同步;如果线程与不同的对象同步,它们可以同时进入同步块。

实例方法中的synchronized关键字表示该块由该实例同步。由于您正在调用bow两个不同对象的方法,因此无法控制两者同时执行此类功能。

通过类对象同步(或使用为此创建的静态最终对象)。

于 2012-11-26T10:19:15.840 回答
1

-你已经使用了2 objects这里的两个线程都使用了 2 个不同的监视器锁。

-由于两个线程都已锁定2 different object,很明显线程 1 在对象 1 上的锁定对线程 2 获取对象 2 的锁定没有影响。

-您在这里使用synchronized了需要对象锁的关键字,并且您为两个线程提供了自己的对象锁,因此线程 2 进入弓。

于 2012-11-26T10:19:22.880 回答
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());
    }
}
于 2012-11-26T10:31:12.093 回答