Bei der Verarbeitung von Java -Thread -Parallelität besteht die Verwendung eines Keywords Volatile sehr verwirrt. Ich denke, dass die Verwendung dieses Keywords alles gut läuft, wenn die Verarbeitung von Multi-Threaded-Gleichzeitverarbeitung verwendet wird.
Die Java-Sprache unterstützt Multi-Threading. Um das Problem der Genauigkeit der Gewinde zu lösen, werden der Synchron Block und den flüchtigen Schlüsselwortmechanismus in der Sprache eingeführt.
synchronisiert
Jeder kennt synchronisierte Blöcke und werden über das synchronisierte Schlüsselwort implementiert. Bei synchronisierten und blockierten Anweisungen kann sie bei einem Zugriff auf Multi-Threads gleichzeitig gleichzeitig verwenden.
Synchronisierte modifizierte Methode oder Codeblock.
flüchtig
Bei Variablen, die mit volatilem modifiziertem modifiziert sind, liest der Thread bei jeder Verwendung der Variablen den modifiziertesten Wert der Variablen. Flüchtigen Sie sich leicht missbraucht und für atomare Operationen verwendet.
Lassen Sie uns unten ein Beispiel sehen. Wir implementieren einen Zähler. Jedes Mal, wenn der Thread startet, wird die Zähler -Inc -Methode aufgerufen, um dem Zähler einen hinzuzufügen.
Ausführungsumgebung - JDK -Version: JDK1.6.0_31, Speicher: 3G CPU: x86 2.4g
public class counter {public static int count = 0; public static void inc () {// Die Verzögerung hier ist 1 Millisekunde, wobei das Ergebnis offensichtlich versucht. <1000;Auslaufergebnis: count.count = 995
Das tatsächliche Betriebsergebnis kann jedes Mal unterschiedlich sein. Das Ergebnis der Maschine ist: Auslaufergebnis: Zähler.Count = 995. Es ist zu erkennen, dass die Anzahl in einer Umgebung mit mehreren Threads nicht erwartet, dass das Ergebnis 1000 beträgt.
Viele Menschen denken, dass dies ein Problem mit mehreren Thread-Parallelen ist. Sie müssen nur vor der variablen Anzahl volatile hinzufügen, um dieses Problem zu vermeiden. Dann ändern wir den Code, um festzustellen, ob das Ergebnis unseren Erwartungen entspricht.
public class counter {public volatile static int count = 0; public static void inc () {// Die Verzögerung ist 1 Millisekunde, wodurch das Ergebnis offensichtlich versuchte {thread.sleep (1);} catch (interruptedException e) {} count ++;} öffentliche statische Void -Main (Saiten -Arguming) {// Int 1000 -Threads. 0;Auslaufergebnis: count.count = 992
Das Betriebsergebnis ist immer noch nicht so 1000, wie wir erwartet hatten. Lassen Sie uns die folgenden Gründe analysieren
Im Artikel der Java -Müllsammlung wird die Zuweisung des Gedächtnisses im Moment von JVM beschrieben. Einer der Speicherbereiche ist der JVM Virtual Machine Stack, und jeder Thread hat einen Fadenstapel, wenn er ausgeführt wird.
Der Thread -Stack speichert die Informationen zur Variablenwert während der Thread -Laufzeit. Wenn ein Thread auf den Wert eines bestimmten Objekts zugreift, finden Sie zuerst den Wert der Variablen, die dem Heap -Speicher über die Referenz des Objekts entspricht
Der spezifische Wert der Variablen wird in den lokalen Speicher des Threads geladen und eine Kopie der Variablen erstellt. Danach hat der Thread keine Beziehung mehr zum variablen Wert des Objekts im Heap -Speicher, sondern den Wert der Kopiervariablen direkt.
In einem bestimmten Zeitpunkt nach der Änderung (vor dem Thread) wird der Wert der Thread -Variablenkopie automatisch auf die Objektvariable im Heap zurückgeschrieben. Auf diese Weise ändert sich der Wert des Objekts im Haufen. Das folgende Bild
Lesen und laden Sie die Kopiervariablen vom Hauptspeicher zum aktuellen Arbeitsspeicher
Verwenden und zuweisen ausführende Code, um den freigegebenen Variablenwert zu ändern
Speichern und schreiben
Wo verwendet und zuweisen können, können mehrmals angezeigt werden
Diese Operationen sind jedoch nicht atomar, dh nach der Änderung der Hauptspeicherzahlvariablen führt der Wert im Arbeitsspeicher des Threads nicht zu entsprechenden Änderungen, da sie geladen wurde. Das berechnete Ergebnis unterscheidet sich daher von den Erwartungen.
Für Variablen, die durch volatile modifiziert wurden, stellt die virtuelle JVM -Maschine nur sicher, dass der von dem Hauptspeicher zum Thread -Arbeitsspeicher geladene Wert der neueste ist
Wenn beispielsweise Thread 1 und Thread 2 Lese- und Ladevorgänge ausführen und feststellen, dass der Wert der Anzahl im Hauptspeicher 5 ist, wird der neueste Wert geladen
Nachdem die Heap -Anzahl in Thread 1 modifiziert wurde, wird sie in den Hauptspeicher geschrieben, und die Zählvariable im Hauptspeicher wird 6.
Da Thread 2 bereits den Lese- und Ladevorgang durchgeführt hat, wird der variable Wert der Hauptspeicherzahl auch nach dem Vorgang auf 6 aktualisiert.
Dies führt dazu, dass die Parallelität nach zwei Threads mit dem flüchtigen Schlüsselwort rechtzeitig geändert wurde.
Das obige ist die Bedeutung des volatilen Schlüsselworts in Java, das Ihnen vom Herausgeber vorgestellt wurde. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!