Wie kann System.out.format einen Deadlock verhindern?

Ich habe das einschließlich eines Aufrufs von System.out.format im klassischen gefundenJava Deadlock Tutorial verhindert Deadlock, und ich kann nicht herausfinden, warum.

Der folgende Code ist derselbe wie der des Tutorials, mit dem Zusatz zumain vonSystem.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.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) throws InterruptedException {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston = new Friend("Gaston");

        System.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.getName());

        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();

        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

Hier ist die Ausgabe:

Hi, I'm Alphonse...no deadlock for you!

Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed back to me!
Gaston: Alphonse has bowed to me!
Alphonse: Gaston has bowed back to me!

Das Entfernen der fehlerhaften Leitung führt zum üblichen Deadlock:

Alphonse: Gaston has bowed to me!
Gaston: Alphonse has bowed to me!
... deadlock ...

Verändert der Aufruf von System.out.format irgendwie die Art und Weise, in der die Threads die intrinsischen Sperren für die Objekte erhalten?

Aktualisieren:

Ich konnte das System wieder zum Deadlock bringen, indem ich einfach änderte, wo ich die Threads im Code starte:

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

    System.out.format("Hi, I'm %s...no deadlock for you!\n\n", alphonse.getName());

    Thread t1 = new Thread(new Runnable() {
        public void run() { alphonse.bow(gaston); }
    });

    Thread t2 = new Thread(new Runnable() {
        public void run() { gaston.bow(alphonse); }
    });

    t1.start();
    t2.start();
}

Dies wirft die Frage auf, wie wir einen besseren Einblick in das Verhalten des Thread-Schedulers erhalten können, aber das werde ich für einen anderen Tag aufheben.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage