Роль System.out.format в примере тупика Oracle - PullRequest
1 голос
/ 15 апреля 2020

Я просматривал несколько примеров тупиковой ситуации и заметил интересную вещь во время игры с образцом Oracle: https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html.

Если вы подставите эту строку: System.out. формат ("% 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();
    }
}

1 Ответ

2 голосов
/ 15 апреля 2020

Это вызвано условием гонки .

System.out.format(...); намного медленнее, чем System.out.println(...).

При println(), строка для печати создается вызывающей стороной, поэтому все, что нужно сделать println(), это напечатать эту строку.

При format() (или printf()) строка для печати строится внутри метода, тогда как метод имеет синхронизированный замок. Кроме того, метод должен анализировать строку формата, сложность которой отсутствует с println(), где это простая конкатенация строк.

Так, с format() код достаточно медленный, чтобы 2 потока могли введите методы одновременно.

При println код выполняется быстрее, поэтому вероятность одновременного входа обоих методов в методы намного меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...