Ich habe einen Code, der so aussieht:
Snippet A:
%Vor% Da das Lesen von numCreated
nicht synchronisiert ist, wenn Thread-A ein Creature
um 13 Uhr erstellt und Thread-B numCreated()
um 14 Uhr liest, hat numCreated()
möglicherweise entweder 0 oder zurückgegeben 1 (auch wenn Thread-A das Objekt um 1.05 Uhr initialisiert hat).
Also habe ich synchronized
zu numCreated()
hinzugefügt:
Snippet B :
%Vor% und alles ist gut, außer dass ich dachte, wenn ich es zu Snippet C modifiziere, ist die Variable numCreated
noch richtig synchronisiert?
Snippet C:
%Vor% Mit Snippet C ist garantiert, dass sobald Thread-A die Objektgenerierung um 13:05 Uhr beendet, der Aufruf von Thread-B an numCreated()
sicher 1
zurückgibt?
PS: Ich verstehe, dass ich in einer realen Situation wahrscheinlich ein AtomicLong
verwenden würde, aber das ist für Lernzwecke
Siehe Zypern :
Es erfolgt ein Schreibvorgang in ein flüchtiges Feld - vor jedem weiteren Lesen von das gleiche Feld. Schreibt und liest flüchtige Felder ähnlich Memory Consistency-Effekte als Eingabe und Beenden von Monitoren, aber tun keine gegenseitige Ausschlussverriegelung.
Also ist die Antwort ja. Das Schreiben des Volatile im Konstruktor geschieht vor dem Lesen des Volatile in numCreated()
. Und da die nicht-atomare Inkrementierung immer noch in einem synchronisierten Block erfolgt, ist die Synchronisation in Ordnung (die Inkrementierung ist nicht atomar, sondern das Schreiben des volatilen long ist).
Tags und Links java multithreading concurrency