Antworten:
Kurze Antwort lautet: Nein.
Aus der java.util.concurrent.atomicPaketdokumentation. Zitieren:
Die Memory-Effekte für Zugriffe und Aktualisierungen von Atomics folgen im Allgemeinen den Regeln für flüchtige Stoffe:
gethat die Memory-Effekte des Lesens einervolatileVariablen.sethat die Memory-Effekte des Schreibens (Zuweisens) einervolatileVariablen.
Diese Dokumentation ist übrigens sehr gut und alles wird erklärt.
AtomicReference::lazySetist eine neuere (Java 6+) Operation, deren Semantik durch volatileVariablen nicht erreicht werden kann. Weitere Informationen finden Sie in diesem Beitrag .
Es gibt verschiedene Unterschiede und Kompromisse:
Die Verwendung eines AtomicReferenceget / set hat dieselbe JMM-Semantik wie ein flüchtiges Feld (wie im Javadoc angegeben), aber das AtomicReferenceist ein Wrapper um eine Referenz, sodass jeder Zugriff auf das Feld eine weitere Zeigerjagd erfordert .
Der Speicherbedarf wird multipliziert (unter der Annahme einer komprimierten OOP-Umgebung, was für die meisten VMs gilt):
AtomicReference = 4b + 16b (12b Objektkopf + 4b Referenzfeld)AtomicReferencebietet eine umfangreichere API als eine flüchtige Referenz. Sie können die API für die flüchtige Referenz mithilfe von a AtomicFieldUpdateroder mit Java 9 a wiederherstellen VarHandle. Sie können auch geradeaus greifen, sun.misc.Unsafewenn Sie gerne mit einer Schere laufen. AtomicReferenceselbst wird mit implementiert Unsafe.
Wann ist es also gut, einen über den anderen zu wählen:
AtomicReference/ AtomicFieldUpdater/ Unsafewo Sie dazu neigen, in Bezug auf Lesbarkeit und Risiko für Ihren Leistungsgewinn zu zahlen. Wenn dies kein sensibler Bereich ist, gehen Sie einfach für AtomicReference. Bibliotheksschreiber verwenden normalerweise eine Mischung dieser Methoden, abhängig von den Ziel-JDKs, den erwarteten API-Einschränkungen, den Speicherbeschränkungen usw.JDK-Quellcode ist eine der besten Möglichkeiten, um solche Verwirrungen zu beantworten. Wenn Sie sich den Code in AtomicReference ansehen, wird eine volatie-Variable für die Objektspeicherung verwendet.
private volatile V value;
Wenn Sie also nur get () und set () für AtomicReference verwenden, ist dies wie die Verwendung einer flüchtigen Variablen. Wie andere Leser kommentierten, bietet AtomicReference zusätzliche CAS-Semantik. Entscheiden Sie also zuerst, ob Sie eine CAS-Semantik wünschen oder nicht, und verwenden Sie AtomicReference nur dann.
AtomicReferencebietet zusätzliche Funktionen, die eine einfache flüchtige Variable nicht bietet. Wenn Sie die API Javadoc gelesen haben, wissen Sie dies, aber es bietet auch eine Sperre, die für einige Vorgänge nützlich sein kann.
Sofern Sie diese zusätzliche Funktionalität nicht benötigen, empfehlen wir Ihnen, ein einfaches volatileFeld zu verwenden.
volatileFeld kann wie jedes reguläre Feld verwendet werden, während für den Zugriff auf den Wert in a Methoden und Methoden AtomicReferenceerforderlich sind. getset
Manchmal ist AtomicReference eine gute Wahl, selbst wenn Sie nur Gets und Sets verwenden:
Beispiel mit flüchtigen Bestandteilen:
private volatile Status status;
...
public setNewStatus(Status newStatus){
status = newStatus;
}
public void doSomethingConditionally() {
if(status.isOk()){
System.out.println("Status is ok: " + status); // here status might not be OK anymore because in the meantime some called setNewStatus(). setNewStatus should be synchronized
}
}
Die Implementierung mit AtomicReference bietet Ihnen eine kostenlose Copy-on-Write-Synchronisation.
private AtomicReference<Status> statusWrapper;
...
public void doSomethingConditionally() {
Status status = statusWrapper.get();
if(status.isOk()){
System.out.println("Status is ok: " + status); // here even if in the meantime some called setNewStatus() we're still referring to the old one
}
}
Man könnte sagen, dass Sie immer noch eine richtige Kopie haben könnten, wenn Sie ersetzen würden:
Status status = statusWrapper.get();
mit:
Status statusCopy = status;
Es ist jedoch wahrscheinlicher, dass der zweite in Zukunft versehentlich von jemandem während der "Code-Reinigung" entfernt wird.