Warum brauchen wir nicht flüchtig mit StampedLock?

9

Gegeben ein Codebeispiel aus Oracle-Dokumenten Ссылка

%Vor%

Und vorausgesetzt, dass alle Methoden der Klasse Point aus verschiedenen Threads aufgerufen werden können:

Warum brauchen wir die Felder x und y nicht unbedingt als flüchtig deklarieren?

Ist sichergestellt, dass der Code, der die Methode Point#moveIfAtOrigin ausführt, nach dem Erwerb von StampedLock#readLock ?

immer die frischesten Änderungen an den Feldern x und y sehen würde?

Wird irgendeine Art von Speicherbarriere eingerichtet, wenn wir StampedLock#writeLock , StampedLock#readLock ?

aufrufen?

Könnte jemand auf ein Zitat aus der Dokumentation verweisen?

    
Dmitry Gorbunov 30.08.2017, 09:05
quelle

2 Antworten

2

Ich kann nicht sagen, warum das im Dokument nicht explizit erwähnt wird - vielleicht weil es irgendwie impliziert ist, aber intern, dass Unsafe.compareAndSwapLong was in LOCK CMPXCHG bedeutet, was für x86 % co_de bedeutet % (Ich nehme an, dass so etwas auf anderen Plattformen gemacht wird); es ist also nicht notwendig, dass diese% in der Tat% sind.

Tatsächlich hat jede Anweisung in full memory barrier mit einem volatile eine volle Speicherbarriere.

    
Eugene 30.08.2017, 09:21
quelle
2

Der Javadoc der Lock Schnittstelle gibt folgendes an:

  

Speichersynchronisierung

     

Alle Lock-Implementierungen müssen die gleiche Speichersynchronisierungssemantik erzwingen, die von der integrierten Monitorsperre bereitgestellt wird, wie in Die Java-Sprachspezifikation (17.4 Speichermodell) beschrieben:

     

Eine erfolgreiche Sperroperation hat die gleichen Auswirkungen auf die Speichersynchronisierung wie eine erfolgreiche Sperraktion.   Ein erfolgreicher Entsperrvorgang hat dieselben Auswirkungen auf die Speichersynchronisierung wie eine erfolgreiche Entsperraktion.   Fehlgeschlagene Sperr- und Entsperrvorgänge und Wiedereintritts- / Entsperrvorgänge erfordern keine Speichersynchronisationseffekte.

Obwohl StampedLock Lock nicht implementiert, hat es eine Methode wie asReadLock() , dass:

  

Gibt eine einfache Sperransicht dieser StampedLock-Instanz zurück, in der die Lock.lock () -Methode readLock () und ähnlich für andere Methoden zugeordnet ist.

Er gibt eine Instanz von StampedLock 's innerer Klasse ReadLockView zurück, was eine tatsächliche Implementierung von Lock ist.

Da es sich jedoch lediglich um einen Delegator handelt, bedeutet dies, dass die ursprünglichen Methoden Speicherbarrieren erstellen müssen, um der Erzwingung der Speichersynchronisierung der Schnittstelle Lock zu entsprechen.

    
Luciano van der Veekens 30.08.2017 09:34
quelle