Was bedeutet “flüchtig” in Java?

Lesezeit: 6 Minuten

Benutzer-Avatar
jnivasreddy

Wir gebrauchen volatile in einem unserer Projekte, um dieselbe Kopie der Variablen zu verwalten, auf die von verschiedenen Threads zugegriffen wird. Meine Frage ist, ob es in Ordnung ist, es zu verwenden volatile mit static. Der Compiler gibt keine Fehler aus, aber ich verstehe den Grund für die Verwendung beider nicht.

Benutzer-Avatar
ide

Abgesehen vom Lesen der Speichermodellspezifikation empfehle ich Ihnen, sie zu lesen http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html. Es wurde von einem der JMM-Autoren geschrieben und sollte Ihre Frage beantworten. Das Denken des Gedächtnisses liest und schreibt in Bezug auf das passiert-vorher Klausel ist ebenfalls hilfreich; das JMM für Java 5 und höher fügt Happens-Before-Semantik hinzu volatile.

Insbesondere wenn Sie eine flüchtige Variable aus einem Thread lesen, sind alle Schreibvorgänge bis einschließlich des Schreibvorgangs in diese flüchtige Variable von anderen Threads jetzt für diesen einen Thread sichtbar. Wenn Sie etwas Zeit haben, gibt es einen Google Tech Talk, der das Thema weiter behandelt: https://code.google.com/edu/languages/#_java_memmodel.

Und ja, Sie können verwenden static mit volatile. Sie machen verschiedene Dinge.

  • In Bezug auf Ihren zweiten Absatz: Meinen Sie alle Schreibvorgänge in alle Variablen oder alle Schreibvorgänge in diese eine flüchtige Variable?

    – fredoverflow

    29. Mai 2011 um 9:56 Uhr

  • Ich glaube, es sind alle Schreibvorgänge in alle Variablen vor dem letzten Schreibvorgang in die flüchtige Variable, die gelesen wird.

    – ide

    4. Juni 2011 um 1:22 Uhr

  • “Wenn ein Feld als flüchtig deklariert wird, werden der Compiler und die Laufzeit darauf hingewiesen, dass diese Variable gemeinsam genutzt wird und dass Operationen darauf nicht mit anderen Speicheroperationen neu geordnet werden sollten. Flüchtige Variablen werden nicht in Registern oder Caches zwischengespeichert, vor denen sie verborgen sind andere Prozessoren, sodass ein Lesevorgang einer flüchtigen Variablen immer den letzten Schreibvorgang eines beliebigen Threads zurückgibt.” Bloch, Josua; Götz, Brian; Peierls, Tim; Bowbeer, Joseph; Holmes, David; Lea, Doug (2006-05-09). Java-Parallelität in der Praxis (Kindle-Standorte 1194-1197). Pearson Education (USA). Kindle-Edition.

    – James

    6. November 2011 um 17:13 Uhr

  • Die Sichtbarkeitseffekte flüchtiger Variablen gehen über den Wert der flüchtigen Variablen selbst hinaus. Wenn Thread A in eine flüchtige Variable schreibt und anschließend Thread B dieselbe Variable liest, werden die Werte aller Variablen, die für A vor dem Schreiben in die flüchtige Variable sichtbar waren, nach dem Lesen der flüchtigen Variablen für B sichtbar. Bloch, Josua; Götz, Brian; Peierls, Tim; Bowbeer, Joseph; Holmes, David; Lea, Doug (2006-05-09). Java-Parallelität in der Praxis (Kindle-Standorte 1202-1205). Pearson Education (USA). Kindle-Edition.

    – James

    6. November 2011 um 17:13 Uhr

  • Sperrfreie Thread-Synchronisation youtube.com/watch?v=KzDShvKbEMs#t=10m

    – alexmail

    8. September 2012 um 21:25 Uhr


In Java hat volatile eine ähnliche allgemeine Bedeutung wie in C. Das Java-Speichermodell (siehe den hervorragenden Link in der Antwort von ide) ermöglicht es Threads, gleichzeitig einen anderen Wert für als nicht flüchtig markierte Variablen zu “sehen”. Zum Beispiel:

Thread a:

n = 1;
// wait...
n = 2;

Threads B und C:

while (true) {
    System.out.println(name + ": " + n);
}

Diese Ausgabe ist erlaubt (beachten Sie, dass Sie nicht unbedingt zwischen B und C wechseln müssen, ich versuche hier nur, den “Wechsel” von B und C zu zeigen):

C: 1
B: 1
C: 2
B: 1
C: 2
B: 2

Dies ist völlig unabhängig von der Sperre, die von genommen wird println; Faden B ist erlaubt um zu sehen n als 1, selbst nachdem C herausgefunden hat, dass es 2 ist. Dafür gibt es eine Vielzahl sehr guter Gründe, die ich nicht vollständig verstehen kann, viele davon beziehen sich auf die Geschwindigkeit und einige auf die Sicherheit.

Wenn es volatil ist, sind Sie garantiert (abgesehen von der println‘s-Sperre, die ich für den Moment ignorieren werde), dass B und C beide “gleichzeitig” den neuen Wert von B sehen werden, sobald er gesendet wird.

Sie können verwenden volatile mit static weil sie verschiedene Dinge beeinflussen. volatile bewirkt, dass Änderungen einer Variablen auf alle “repliziert” werden Fäden die diese Variable verwenden, bevor sie sie verwenden, während static teilt eine einzige Variable für alle Klassen die diese Variable verwenden. (Dies kann für Leute, die neu in Java sind, ziemlich verwirrend sein, weil jede Thread geschieht als implementiert werden class.)

volatile bedeutet, dass sich die Variable zur Laufzeit ändert und dass der Compiler ihren Wert aus keinem Grund zwischenspeichern sollte.

Dies ist nur wirklich ein Problem, wenn die Variable von Threads gemeinsam genutzt wird. Sie möchten nicht, dass ein Thread mit veralteten Daten arbeitet, sodass der Compiler niemals den Wert von a zwischenspeichern sollte volatile variable Referenz.

Stellen Sie sich ein Szenario vor, in dem zwei Threads (Thread1 und Thread2) auf dieselbe Variable „mObject“ mit dem Wert 1 zugreifen.

Wenn ein Thread1 ausgeführt wird, erwartet er nicht, dass andere Threads die Variable „mObject“ ändern. In diesem Szenario speichert Thread1 die Variable „mObject“ mit dem Wert 1.

Und wenn Thread2 den Wert von ‘mObject’ auf 2 ändert, würde Thread1 den mObject-Wert immer noch als 1 bezeichnen, da es zwischengespeichert hat. Um dieses Caching zu vermeiden, sollten wir die Variable als deklarieren

privates flüchtiges int mObject;

In diesem Szenario erhält Thread1 den aktualisierten Wert von mObject

Benutzer-Avatar
Johnny

Kleine Ausarbeitung, aber das Schlüsselwort volatile dient nicht nur der Sichtbarkeit des Speichers. Vor Java-Ver 1.5 wurde das Schlüsselwort volatile deklariert, dass das Feld den neuesten Wert des Objekts erhält, indem es jedes Mal zum Lesen auf den Hauptspeicher trifft und zum Schreiben löscht.

In den neuesten Java-Versionen sagt das Schlüsselwort volatile zwei sehr wichtige Dinge aus:

  1. Machen Sie sich keine Gedanken darüber, wie, aber wissen Sie, dass Sie beim Lesen eines flüchtigen Felds immer den aktuellsten Wert haben.
  2. Ein Compiler kann einen flüchtigen Lese-/Schreibvorgang nicht umordnen, um die Programmreihenfolge aufrechtzuerhalten.

Überprüfen Sie es für mehr Java flüchtig Beispiele.

  • Die einzige Antwort, die sowohl Caching als auch Neuordnung erwähnt. Plus die Java-Geschichte.

    – Sternchen

    9. März um 10:09 Uhr

Benutzer-Avatar
Lukas de Lima

Das Schlüsselwort Java volatile wird verwendet, um eine Java-Variable als “im Hauptspeicher gespeichert” zu markieren. Genauer gesagt bedeutet dies, dass jeder Lesevorgang einer flüchtigen Variablen aus dem Hauptspeicher des Computers und nicht aus dem CPU-Cache gelesen wird und dass jeder Schreibvorgang in eine flüchtige Variable in den Hauptspeicher und nicht nur in den CPU-Cache geschrieben wird . Der Wert eines Attributs wird nicht Thread-lokal zwischengespeichert und immer aus dem “Hauptspeicher” gelesen.

Das Überwinden des Dateninkonsistenzproblems ist der Vorteil, aber das Lesen und Schreiben in den Hauptspeicher ist teurer als der Zugriff auf den CPU-Cache. Wenn es keine besonderen Anforderungen gibt, wird daher niemals empfohlen, flüchtige Schlüsselwörter zu verwenden.

class Test  
{  
    static int var=5;  
} 

Nehmen Sie im obigen Beispiel an, dass zwei Threads an derselben Klasse arbeiten. Beide Threads laufen auf unterschiedlichen Prozessoren, wobei jeder Thread seine lokale Kopie von var hat. Wenn ein Thread seinen Wert ändert, spiegelt sich die Änderung nicht im Original im Hauptspeicher wider. Dies führt zu Dateninkonsistenz, da der andere Thread den geänderten Wert nicht kennt.

 class Test  
{  
   static volatile int var =5;  
}  

Im obigen Beispiel wird der Wert einer flüchtigen Variablen niemals im Cache gespeichert. Alle Lese- und Schreibvorgänge erfolgen vom und zum Hauptspeicher.

  • Die einzige Antwort, die sowohl Caching als auch Neuordnung erwähnt. Plus die Java-Geschichte.

    – Sternchen

    9. März um 10:09 Uhr

1016090cookie-checkWas bedeutet “flüchtig” in Java?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy