关于Java中的死锁情况的问题 [英] Question About Deadlock Situation in Java

查看:117
本文介绍了关于Java中的死锁情况的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Java中的死锁,这里有来自Sun官方教程的示例代码:


Alphonse和Gaston是朋友,和
伟大的信徒的礼貌。严格的
礼节规则是,当你给
给一个朋友时,你必须保持鞠躬
,直到你的朋友有机会
返回弓。不幸的是,这个
规则不考虑两个朋友可能同时向对方鞠躬

的可能性。




  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向我屈服!%n,
this.name ,bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower){
System.out.format(%s:%s已经回到我!%n,
这个。 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);}
})。
new Thread(new Runnable(){
public void run(){gaston.bow(alphonse);}
})。
}
}

这里是Sun的解释:


当Deadlock运行时,
极有可能是两个线程在尝试调用bowBack时阻塞

每个块都将永远结束,因为
每个线程正在等待另一个
退出bow。


我似乎不太喜欢。当alphonse.bow(gaston)运行时,bow方法被锁定。所以现在它会先打印Gaston向我has了!然后它会继续,并调用bowBack,并锁定bowBack以及。这怎么会导致死锁?我是否误解当同步方法被调用时会发生什么?



如果有人可以给我一个简单的解释,谢谢。

解决方案

需要注意的一点是,它不是被锁定的方法,而是对象实例



当调用 alphonse.bow(gaston)时,它会尝试获取 alphonse 。一旦它有锁,它打印一个消息,然后调用 gaston.bowBack(alphonse)。此时,它尝试获取 gaston 上的锁。一旦它有锁,它打印一个消息,然后释放锁,最后锁定 alphonse 被释放。




  • 线程1:获取所有线程锁定 alphonse

  • 主题2:取得 gaston >
  • 主题1:打印邮件

  • 主题1:尝试在 gaston

  • 线程2:尝试获取 alphonse上的锁定 - 不能,因为第1个线程已有它。


I'm learning about deadlocks in Java, and there's this sample code from Sun's official tutorial:

Alphonse and Gaston are friends, and great believers in courtesy. A strict rule of courtesy is that when you bow to a friend, you must remain bowed until your friend has a chance to return the bow. Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time.

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();
    }
}

Here's Sun's explanation:

When Deadlock runs, it's extremely likely that both threads will block when they attempt to invoke bowBack. Neither block will ever end, because each thread is waiting for the other to exit bow.

I don't quite seem to follow. When alphonse.bow(gaston) runs, the bow method is locked. So now it'll first print "Gaston has bowed to me!". Then it'll go on and call bowBack, and locks bowBack as well. How can this cause a deadlock? Am I misunderstanding what happens when a synchronized method is called?

If someone can give me a easy explanation, thanks.

解决方案

One important point to note is that it is not methods which are locked but object instances.

When you call alphonse.bow(gaston), it tries to acquire the lock on alphonse. Once it has the lock, it prints a message, then calls gaston.bowBack(alphonse). At this point, it tries to acquire the lock on gaston. Once it has the lock, it prints a message, then releases the lock, and finally the lock on alphonse is released.

In deadlock, the locks are acquired in such an order that there's no way for either thread to proceed.

  • Thread 1: acquires lock on alphonse
  • Thread 2: acquires lock on gaston
  • Thread 1: prints message
  • Thread 1: tries to acquire lock on gaston - can't, because Thread 2 already has it.
  • Thread 2: prints message
  • Thread 2: tries to acquire lock on alphonse - can't, because Thread 1 already has it.

这篇关于关于Java中的死锁情况的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆