我不明白为什么这段代码会导致死锁

时间:2019-09-11 08:08:33

标签: java concurrency deadlock synchronized

我正在关注有关并发性的oracle文档,在deadlock section中,他们使用以下示例。问题是我不太了解为什么会导致死锁。

正如我所看到的,这就是我正在发生的事情:

  • 阿方斯向加斯顿鞠躬,并获得了bow方法的锁定
  • Alphonse离开了bow方法,进入bowBack,释放了第一个锁并获得了第二个锁。
  • Gaston重复该过程

但是我一定是错的,因为如果您运行代码,则会导致死锁……我在这里错过了什么?

非常感谢!

public class Deadlock
{
    public static void main(String[] args)
    {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston = new Friend("Gaston");

        new Thread(() -> alphonse.bow(gaston)).start();
        new Thread(() -> gaston.bow(alphonse)).start();
    }


    static class Friend
    {
        private final String name;


        Friend(final String name)
        {
            this.name = name;
        }


        String getName()
        {
            return name;
        }


        synchronized void bow(final Friend bower)
        {
            System.out.printf("%s: %s has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }


        synchronized void bowBack(final Friend bower)
        {
            System.out.printf("%s: %s has bowed back to me!%n", this.name, bower.getName());
        }
    }
}

2 个答案:

答案 0 :(得分:4)

假设两个线程都位于bow行的System.out.printf中。当他们尝试调用bowBack时,他们都需要在bow返回并释放锁之前获取另一个实例的锁。

由于两个线程都被锁定,等待彼此解锁,所以这是一个死锁。

答案 1 :(得分:1)

  

Alphonse离开了bow方法,进入bowBack,释放了第一个锁并获得了第二个锁。

这是您的问题-从bowBack调用bow时不会释放锁,但是现在您还需要获取另一个对象的锁。只能在您退出bow方法时退出锁,只有在退出从其调用的bowBack方法后,锁才会发生。