Aus dem Buch Java Concurrency in der Praxis:
Um ein Objekt sicher zu veröffentlichen, müssen sowohl die Referenz auf das Objekt und die Objektstatus muss sichtbar gemacht werden für andere Threads gleichzeitig. EIN richtig konstruiertes Objekt sein kann sicher veröffentlicht von:
Initialisieren einer Objektreferenz von einem statischen Initialisierer
Speichern einer Referenz darauf in einem flüchtigen Feld oder AtomicReference
Speichern einer Referenz darauf in einem letzten Feld eines ordnungsgemäß konstruierten Objekt
Speichern eines Verweises auf ein Feld, das von einem
ordnungsgemäß geschützt wird sperren.
Meine Fragen sind:
volatile
approach und final
approach in Bezug auf die sichere Veröffentlichung des Objekts. this
-Referenz nicht erlaubt, zu entkommen). Aber noch einmal, warum haben sie über richtig konstruierte Objekte erwähnt? Was sind die Unterschiede zwischen den Aufzählungszeichen 2 und 3?
volatile
bedeutet grundsätzlich, dass alle Schreibvorgänge in diesem Feld von anderen Threads aus sichtbar sind. Wenn Sie also ein Feld als volatil deklarieren: private volatile SomeType field;
, ist garantiert, dass, wenn der Konstruktor in dieses Feld schreibt: field = new SomeType();
, diese Zuweisung für andere Threads sichtbar ist, die anschließend versuchen, field
. final
hat eine ähnliche Semantik: Sie haben die Garantie, dass, wenn Sie ein letztes Feld haben: private final SomeType field;
das Schreiben in dieses Feld (entweder in der Deklaration oder im Konstruktor): field = new SomeType();
wird nicht reorganisiert und wird es sein sichtbar durch andere Threads wenn das Objekt korrekt publiziert wurde (dh kein Entweichen von this
zum Beispiel). Offensichtlich ist der Hauptunterschied, dass wenn das Feld endgültig ist, Sie es nur einmal zuweisen können.
Was meint er mit dem letzten Feld eines korrekt konstruierten Objekts in Punkt 3?
Wenn Sie zum Beispiel this
aus dem Konstruktor entkommen lassen, ist die Garantie der letzten Semantik weg: Ein Beobachtungs-Thread sieht das Feld möglicherweise mit seinem Standardwert (null für ein Objekt). Wenn das Objekt richtig konstruiert ist, kann dies nicht passieren.
Contrived Beispiel:
%Vor% Es gibt keinen Unterschied in den Auswirkungen der Veröffentlichung von volatile
vs final
, außer dass final
nur einmal im Konstruktor gesetzt werden kann und das, was Sie lesen, sollte sich niemals ändern.
Ich glaube, dass ein korrekt konstruiertes Objekt tatsächlich das ist, worauf Sie verweisen, ein Objekt, dessen this
-Referenz den Konstruktor nicht verlassen hat und auf sichere Weise für den verwendeten Thread veröffentlicht wurde in.
Tags und Links java java-memory-model