Java Memory Model: Ist es sicher, ein zyklisches Referenzdiagramm der endgültigen Instanzfelder zu erstellen, die alle im selben Thread zugewiesen sind?

Kann jemand, der das Java-Speichermodell besser versteht als ich, bestätigen, dass der folgende Code korrekt synchronisiert ist?

class Foo {
    private final Bar bar;

    Foo() {
        this.bar = new Bar(this);
    }
}

class Bar {
    private final Foo foo;

    Bar(Foo foo) {
        this.foo = foo;
    }
}

Ich verstehe, dass dieser Code korrekt ist, aber ich habe das ganze @ nicht durchgearbeit passiert-vor Mathematik. Ich habe zwei informelle Zitate gefunden, die darauf hindeuten, dass dies rechtmäßig ist, obwohl ich ein bisschen vorsichtig bin, mich vollständig auf sie zu verlassen:

Das Verwendungsmodell für endgültige Felder ist einfach: Legen Sie die endgültigen Felder für ein Objekt im Konstruktor dieses Objekts fest. Schreiben Sie keinen Verweis auf das zu erstellende Objekt an einer Stelle, an der ein anderer Thread es sehen kann, bevor der Konstruktor des Objekts abgeschlossen ist. Wenn dies befolgt wird und das Objekt von einem anderen Thread gesehen wird, wird diesem Thread immer die korrekt konstruierte Version der letzten Felder des Objekts angezeigt. Es werden auch Versionen von Objekten oder Arrays angezeigt, auf die von den endgültigen Feldern verwiesen wird, die mindestens so aktuell sind wie die endgültigen Felder. Die Java®-Sprachspezifikation: Java SE 7 Edition, Abschnitt 17.5]

Eine andere Referenz:

Was bedeutet es, dass ein Objekt richtig konstruiert ist? Es bedeutet einfach, dass kein Verweis auf das Objekt, das konstruiert wird, während des Konstruierens "entkommen" darf. (Beispiele finden Sie unter Sichere Konstruktionstechniken.) Platzieren Sie mit anderen Worten keinen Verweis auf das zu konstruierende Objekt an einer Stelle, an der ein anderer Thread es möglicherweise sehen kann. Weisen Sie es keinem statischen Feld zu, registrieren Sie es nicht als Listener für ein anderes Objekt usw. Diese Aufgaben sollten nach Abschluss des Konstruktors ausgeführt werden, nicht im Konstruktor. JSR 133 (Java Memory Model) FAQ, "Wie funktionieren endgültige Felder unter dem neuen JMM?"]

Antworten auf die Frage(4)

Ihre Antwort auf die Frage