Java Volatile Keywords
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
öffentliche Klasse Zähler {public static int count = 0; public static void inc () {// Die Verzögerung hier ist 1 Millisekunde, wodurch das Ergebnis offensichtlich versucht wird {Thread.sleep (1); } catch (InterruptedException e) {} count ++; } public static void main (String [] args) {// 1000 Threads gleichzeitig starten, um i ++ -Rechnungen durchzuführen und das tatsächliche Ergebnis für (int i = 0; i <1000; i ++) {neuer Thread (new Runnable () {@Override public void run () {counter ();}}). } // Der Wert jedes Laufs hier kann unterschiedlich sein, möglicherweise 1000 System.out.println ("Run Ergebnis: count.count =" + counter.count); }}运行结果:Counter.count= 995
实际运算结果每次可能都不一样,本机的结果为:运行结果:Counter.count= ,可以看出,在多线程的环境下,Counter.count并没有期望结果是Ergebnis der nativen Maschine ist 1000实际运算结果每次可能都不一样,本机的结果为:运行结果:Counter.count= 995
Viele Menschen denken, dass dies ein Problem mit mehreren Thread-Parallelen ist. Sie müssen nur很多人以为,这个是多线程并发问题,只需要在变量count之前加上volatile hinzufügen就可以避免这个问题,那我们在修改代码看看,看看结果是不是符合我们的期望
Public Class Counter {public volatile statische int count = 0; public static void inc () {// Die Verzögerung hier ist 1 Millisekunde, wodurch das Ergebnis offensichtlich versucht wird {Thread.sleep (1); } catch (InterruptedException e) {} count ++; } public static void main (string [] args) {// 1000 Threads gleichzeitig starten, i ++ berechnungen durchführen und das tatsächliche Ergebnis für (int i = 0; i <1000; i ++) {neuer Thread (neuer Runnable () {@Override public void run () {coup.inc ();}}). } // Der Wert eines jeden Laufs hier kann unterschiedlich sein, möglicherweise 1000 system.out.println ("Run Ergebnis: count.count =" + counter.count); }}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
Beschreiben Sie diese Wechselwirkung zum Schreiben
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.
Danke fürs Lesen, ich hoffe, es kann Ihnen helfen. Vielen Dank für Ihre Unterstützung für diese Seite!