final vs volatile guarantee w.rt zur sicheren Veröffentlichung von Objekten

8

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:

  1. Was sind die Unterschiede zwischen den Aufzählungszeichen 2 und 3? Mich interessiert der Unterschied zwischen volatile approach und final approach in Bezug auf die sichere Veröffentlichung des Objekts.
  2. Was meint er mit Endfeld eines ordnungsgemäß konstruierten Objekts in Punkt 3? Vor dem Aufrufen der Aufzählungspunkte haben die Autoren bereits erwähnt, dass sie von einem korrekt konstruierten Objekt sprechen (von dem ich anmaße, dass es der this -Referenz nicht erlaubt, zu entkommen). Aber noch einmal, warum haben sie über richtig konstruierte Objekte erwähnt?
Geek 09.02.2013, 17:03
quelle

2 Antworten

7
  

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 .
  • zu lesen
  • 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%     
assylias 09.02.2013, 19:09
quelle
1

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.

    
Steven Schlansker 09.02.2013 19:10
quelle

Tags und Links