java - 有关Java死锁情况的问题

标签 java concurrency deadlock

我正在学习Java的死锁,并且有来自Sun官方教程的以下示例代码:

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

这是Sun的解释:

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.



我似乎不太了解。当alphonse.bow(gaston)运行时,bow方法被锁定。因此,现在它将首先打印“Gaston向我鞠躬!”。然后它将继续并调用bowBack,并同时锁定bowBack。这怎么会造成僵局?我是否误解了调用同步方法时会发生什么?

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

最佳答案

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

当您调用alphonse.bow(gaston)时,它将尝试获取对alphonse的锁定。拥有锁后,它将打印一条消息,然后调用gaston.bowBack(alphonse)。此时,它尝试获取对gaston的锁定。一旦获得了锁,它将打印一条消息,然后释放该锁,最后释放alphonse上的锁。

在死锁中,锁的获取顺序使得任何一个线程都无法继续执行。

  • 线程1:获取对alphonse的锁定
  • 线程2:获取对gaston的锁定
  • 线程1:打印消息
  • 线程1:尝试获取gaston的锁-不能,因为线程2已经拥有它。
  • 线程2:打印消息
  • 线程2:尝试获取对alphonse的锁定-不能,因为线程1已经拥有它。
  • 关于java - 有关Java死锁情况的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35299310/

    相关文章:

    java - 停止提交给 ExecutorService 的 Runnable

    java - 在 JFrame Java 中闪烁

    引用子类 : avoid class loading deadlock 的 Java 静态初始化程序

    java - "Comparison method violates its general contract!"但我只比较两个长值?

    java - 寻找一种在 android studio (java) 中的基于文本的游戏中保存游戏数据的方法

    C#:x86-x64 内存模型与 ECMA

    java - .awaitTermination() 是否在执行程序中完成工作之前建立 happens-before?

    postgresql - Postgres : ShareLock Deadlock on transaction

    C++ 终止调用,没有事件异常

    java - 朴素素数测试优化