Von Java Concurrency in der Praxis:Unterschied in Speichermodell Semantik zwischen Endverbrauch und flüchtigen Feldern in Java
Wenn ein Feld volatile deklariert wird, werden die Compiler und Runtime auf in Kenntnis gesetzt, dass dieser Variable gemeinsam genutzt wird und dass Operationen auf es sollte nicht mit anderen Speicheroperationen neu angeordnet werden. Flüchtige Variablen sind nicht in Registern oder in Caches zwischengespeichert, wo sie von anderen Prozessoren versteckt sind, so dass ein Lesen einer flüchtigen Variablen immer die meisten jüngsten Schreiben von einem beliebigen Thread zurückgibt. (p25)
Und
Schluss Felder können nicht geändert werden (obwohl die Objekte, die sie beziehen sich auf können geändert werden, wenn sie wandelbar sind), aber sie haben auch spezielle Semantik unter dem Java-Speichermodell. Es ist die Verwendung von Endfeldern, die die Garantie der Initialisierungssicherheit ermöglicht (siehe Abschnitt 3.5.2) , die unverrückbare Objekte ohne Synchronisation frei zugänglich machen und freigeben kann. (p32)
eine unsichere Veröffentlichung Rezitieren:
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n) // might be true for other threads.
}
}
Der Wert von n
überraschenderweise könnte abgestanden werden durch andere Threads gesehen. Aber final
Modifier würde den Trick tun. Ähnlich wie volatile
, oder? Sind final
Felder intrinsisch volatile
? (eine mögliche Erklärung, warum final volatile
ist nicht erlaubt)
Danke. Die Aussage wurde korrigiert. Die Modifikation ist in Ordnung. Aber bedenken Sie das mitgelieferte Beispiel, final macht auch einige volatile wie Magie sogar während der Initialisierung, so dass es keine veralteten Lesevorgänge gibt, liefert JMM eine ähnliche Semantik für beide? – abksrv
sehe meine feste Antwort. Es ist besser, einige zusätzliche Informationen dort zu platzieren, nicht in Kommentaren :) – Cootri