System.out.format在Oracle死锁示例中的作用

问题描述 投票:1回答:1

我正在研究几个死锁示例,并且在使用Oracle示例:https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html时注意到有趣的事情。

如果替换此行:System.out.format(“%s:%s” +“向我鞠躬!%n”,this.name,bower.getName());

带有:System.out.println(this.name +“向我鞠躬!” + bower.getName());

将不再触发死锁。

有人可以解释原因吗?

从上面的链接添加代码以供将来参考:

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();
    }
}
java deadlock
1个回答
2
投票

竞赛条件引起。

[System.out.format(...);System.out.println(...)慢得多。

使用println(),要打印的字符串是由调用方构建的,因此println()要做的就是打印该字符串。

使用format()(或printf()),将在方法内部构建要打印的字符串,而该方法具有同步锁。此外,该方法还必须解析格式字符串,这种复杂性是println()的简单字符串连接所不具备的。

因此,对于format(),代码足够慢,以至于两个线程无法同时输入方法。

使用println,代码会更快,因此两个线程同时进入方法的可能性要小得多。

© www.soinside.com 2019 - 2024. All rights reserved.