Ist es richtig zu sagen, dass static
dies eine Kopie des Wertes für alle Objekte und bedeutet?volatile
eine Kopie des Werts für alle Threads bedeutet?
Wie auch immer, ein static
variabler Wert wird auch ein Wert für alle Threads sein. Warum sollten wir uns dann dafür entscheiden volatile
?
Antworten:
Das Deklarieren einer statischen Variablen in Java bedeutet, dass nur eine Kopie vorhanden ist, unabhängig davon, wie viele Objekte der Klasse erstellt werden. Auf die Variable kann auch dann zugegriffen werden, wenn sie überhaupt nicht
Objects
erstellt wurde. Threads können jedoch lokal zwischengespeicherte Werte haben.Wenn eine Variable flüchtig und nicht statisch ist , gibt es für jede eine Variable
Object
. An der Oberfläche scheint es also keinen Unterschied zu einer normalen Variablen zu geben, aber völlig anders als statisch . Aber auch mitObject
Feldern kann ein Thread einen Variablenwert lokal zwischenspeichern.Dies bedeutet, dass, wenn zwei Threads gleichzeitig eine Variable desselben Objekts aktualisieren und die Variable nicht als flüchtig deklariert wird, es vorkommen kann, dass einer der Threads einen alten Wert im Cache hat.
Selbst wenn Sie über mehrere Threads auf einen statischen Wert zugreifen , kann jeder Thread seine lokale zwischengespeicherte Kopie haben! Um dies zu vermeiden, können Sie die Variable als statisch flüchtig deklarieren. Dadurch wird der Thread gezwungen, jedes Mal den globalen Wert zu lesen.
Jedoch flüchtig ist kein Ersatz für eine richtige Synchronisation!
Zum Beispiel:
Die
concurrentMethodWrong
gleichzeitige gleichzeitige Ausführung kann zu einem Endwert des Zählers führen, der von Null abweicht!Um das Problem zu lösen, müssen Sie eine Sperre implementieren:
Oder benutze die
AtomicInteger
Klasse.quelle
Unterschied zwischen statisch und flüchtig:
Statische Variable : Wenn zwei Threads (annehmen
t1
undt2
) sind das gleiche Objekt zuzugreifen und eine Variable zu aktualisieren , die als statisch deklariert wird , dann bedeutet dast1
undt2
kann ihre eigene lokale Kopie des gleichen Objekts (einschließlich statischen Variablen) in ihrem jeweiligen Cache machen, so Update Die vont1
der statischen Variablen in ihrem lokalen Cache erstellte wird nicht in der statischen Variablen für dent2
Cache wiedergegeben.Statische Variablen werden im Kontext von Object verwendet, bei dem die von einem Objekt vorgenommenen Aktualisierungen in allen anderen Objekten derselben Klasse wiedergegeben werden , nicht jedoch im Kontext von Thread, bei dem die Aktualisierung eines Threads auf die statische Variable die Änderungen an allen Objekten sofort widerspiegelt Threads (in ihrem lokalen Cache).
Volatile Variable : Wenn zwei Threads (annehmen
t1
undt2
) sind das gleiche Objekt zuzugreifen und eine Variable zu aktualisieren , die als flüchtiges deklariert wird , dann bedeutet dast1
undt2
kann ihre eigene lokale Cache des Objekts macht mit Ausnahme der Variable , die als flüchtigen deklariert wird . Die flüchtige Variable hat also nur eine Hauptkopie, die von verschiedenen Threads aktualisiert wird, und die von einem Thread vorgenommene Aktualisierung der flüchtigen Variablen wird sofort auf den anderen Thread übertragen.quelle
volatile
Variable von verschiedenen CPU-Caches gemeinsam genutzt werden. Dies stellt kein Problem dar, da der Cache das ausschließliche Eigentum an der Cache-Zeile aushandelt, bevor diese geändert wird.Neben anderen Antworten möchte ich ein Bild dafür hinzufügen (Bild leicht verständlich)
static
Variablen können für einzelne Threads zwischengespeichert werden. Wenn in einer Umgebung mit mehreren Threads ein Thread seine zwischengespeicherten Daten ändert, wird dies möglicherweise nicht für andere Threads angezeigt, da sie eine Kopie davon haben.volatile
Durch die Deklaration wird sichergestellt, dass Threads die Daten nicht zwischenspeichern und nur die freigegebene Kopie verwenden .Bildquelle
quelle
Ich denke
static
undvolatile
habe überhaupt keine Beziehung. Ich schlage vor, Sie lesen das Java-Tutorial, um Atomic Access zu verstehen , und warum Sie Atomic Access verwenden, verstehen, was verschachtelt ist , werden Sie eine Antwort finden.quelle
In einfachen Worten,
statisch :
static
Variablen sind der Klasse zugeordnet und nicht mit irgendwelchen Objekt zugeordnet . Jede Instanz der Klasse teilt eine Klassenvariable, die sich an einem festen Ort im Speicher befindetflüchtig : Dieses Schlüsselwort gilt sowohl für die Klasse als auch für Instanz - Variablen.
Schauen Sie sich diesen Artikel von an
Javin Paul
, um flüchtige Variablen besser zu verstehen.In Abwesenheit von
volatile
kein Schlüsselwort vorhanden ist, kann der Wert der Variablen im Stapel jedes Threads unterschiedlich sein. Wenn Sie die Variable alsvolatile
festlegen, erhalten alle Threads den gleichen Wert in ihrem Arbeitsspeicher, und Speicherkonsistenzfehler wurden vermieden.Hier der Begriff
variable
entwederstatic
(Klassen-) Variable oderinstance
(Objekt-) Variable sein.Zu Ihrer Anfrage:
Wenn ich
instance
in meiner Anwendung eine Variable benötige , kann ich diese nicht verwendenstatic
Variable verwenden. Selbst im Fall einerstatic
Variablen kann die Konsistenz aufgrund des Thread-Cache nicht garantiert werden, wie in der Abbildung gezeigt.Verwenden von
volatile
Variablen verringert das Risiko von Speicherkonsistenzfehlern, da bei jedem Schreiben in eine flüchtige Variable eine Beziehung hergestellt wird, die vor dem Lesen derselben Variablen auftritt. Dies bedeutet, dass Änderungen an einer flüchtigen Variablen für andere Threads immer sichtbar sind.Die Verwendung des einfachen Zugriffs auf atomare Variablen ist effizienter als der Zugriff auf diese Variablen über synchronisierten Code
Einige der Klassen im
java.util.concurrent
Paket bieten atomare Methoden, die nicht auf Synchronisation beruhen.Weitere Informationen finden Sie in diesem Artikel zur Steuerung der Parallelität auf hoher Ebene .
Vor allem hat einen Blick auf Atomic Variablen .
Verwandte SE-Fragen:
Flüchtig gegen Atomic
Volatile Boolean vs AtomicBoolean
Unterschied zwischen flüchtig und synchronisiert in Java
quelle
volatile
früher war, aber diese Antwort verdeutlicht mir sehr, warum ich sie nochvolatile
mit derstatic
Variablen verwenden muss.Der Zugriff auf flüchtige Variablenwerte erfolgt direkt aus dem Hauptspeicher. Es sollte nur in Multithreading-Umgebungen verwendet werden. Die statische Variable wird einmal geladen. Wenn es in einer Umgebung mit einem Thread verwendet wird, auch wenn die Kopie der Variablen aktualisiert wird und der Zugriff darauf keinen Schaden anrichtet, da nur ein Thread vorhanden ist.
Wenn nun eine statische Variable in einer Multithreading-Umgebung verwendet wird, gibt es Probleme, wenn man das gewünschte Ergebnis davon erwartet. Da jeder Thread eine eigene Kopie hat, wird ein Inkrement oder Dekrement der statischen Variablen eines Threads möglicherweise nicht in einem anderen Thread angezeigt.
Wenn man die gewünschten Ergebnisse von einer statischen Variablen erwartet und dann flüchtig mit statisch im Multithreading verwendet, wird alles aufgelöst.
quelle
Nicht sicher, ob statische Variablen im lokalen Thread-Speicher zwischengespeichert werden oder NICHT. Aber als ich zwei Threads (T1, T2) ausgeführt habe, die auf dasselbe Objekt (obj) zugegriffen haben, und als der T1-Thread die statische Variable aktualisiert hat, wurde dies in T2 wiedergegeben.
quelle
Wenn wir eine Variable als statisch deklarieren, gibt es nur eine Kopie der Variablen. Wenn also verschiedene Threads auf diese Variable zugreifen, gibt es nur einen Endwert für die Variable (da der Variablen nur ein Speicherplatz zugewiesen ist).
Wenn eine Variable als flüchtig deklariert wird, haben alle Threads eine eigene Kopie der Variablen, aber der Wert wird aus dem Hauptspeicher übernommen. Daher ist der Wert der Variablen in allen Threads gleich.
In beiden Fällen ist der Hauptpunkt, dass der Wert der Variablen für alle Threads gleich ist.
quelle