我从甲骨文那里得到了这个死锁示例代码。

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

如果我像下面这样改变函数弓,我可以解决死锁问题。
public void bow(Friend bower) {
    synchronized(this) {
        System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
    }
    bower.bowBack(this);
}

我能用其他方法来解决这个死锁问题吗?
特别是,我想知道thread.sleep()可以解决死锁问题,以及如何使用它。
你能告诉我thread.sleep()和其他方法的可能性吗?
多谢

最佳答案

发生死锁是因为发生了以下方法调用:
alphonse calls bow(),获取alphonse/bow锁
Gaston调用bow(),获取Gaston/bow锁
阿尔方斯让加斯顿退后(),并等待加斯顿完成该动作。
加斯顿让阿尔方斯向后鞠躬(),并等待阿尔方斯完成该动作。
因此,双方都在等待对方完成弓背(),以便完成他们的弓背(),但在他们完成弓背()之前无法开始他们自己的弓背。僵局。
解决方案有效的原因是bowback(this)调用不在synchronized块内。
聪明地使用锁可以更清楚地说明死锁发生的原因和确切位置,并可以防止死锁发生。java的信号量类是一个很好的研究对象。
要实际修复它(防止死锁,但保持线程安全),您必须扩展问题-当Gaston等待Alphonse完成bow()以执行自己的bow()时,会发生什么情况,但Alphonse需要Gason执行bowback()以完成?一个明智的解决方案是,gaston在调用bowback()时放弃执行bow(),而只执行bowback(),但这都取决于您试图解决的问题。

09-12 23:47