In der Java-Multi-Thread-Programmierung wird häufig volatil gefunden. Manchmal wird dieses Schlüsselwort oft mit synchronisiertem oder Sperren verwechselt. Die spezifische Analyse ist wie folgt:
In einer Umgebung mit mehreren Threads wird es ein Problem der Sichtbarkeit von Mitgliedervariablen geben: Jeder Thread in Java verfügt über einen Speicherraum eines Thread-Stapels, der die variablen Informationen des Threads beim Ausführen speichert. Wenn ein Thread auf einen bestimmten variablen Wert zugreift, wird zunächst der Heap -Speicher des Objekts oder den spezifischen Inhalt des Stapels (natives Datentyp) basierend auf der Adresse der Variablen ermittelt und dann denselben Wert im Thread -Stapel dieses Threads speichern. Anschließend haben alle Vorgänge in dieser Variablen nichts mit dem variablen Inhalt im Stapel zu tun, bevor der Thread ausgeht. Es arbeitet mit der Kopie im Thread -Stapel. Nach Abschluss der Operation wird das Ergebnis der Operation in den Hauptspeicher zurückgeschrieben. Wenn es zwei Threads A und B gibt und Kollegen eine bestimmte Variable x betreiben; A fügt 1 zu x hinzu, dann kann die durch B erhaltene Kopie das Ergebnis von x plus 1 oder x sein; Um sicherzustellen, dass die neueste Datenvariable im Speicher erforderlich ist, um das volatile Schlüsselwort hinzuzufügen. Jedes Mal, wenn Sie mit X arbeiten, überprüfen Sie, ob der Wert der Variablen im Thread -Stapel der Wert der Variablen im Speicher entspricht und wenn sie unterschiedlich ist, wird sie erneut geladen.
z.B:
öffentliche Klasse -Threadsee {// Der T1 -Thread führt entsprechende Operationen basierend auf dem Wert des Flags aus, und der Haupt -Thread ändert den Wert der t1 public static void main (String [] args) unterbrochene Ausnahme (ThreadTest th = neuer Threadtest (); Thread T1 = neuer Thread (th); t1.start (); Thread.sleep (1000); th.changeflag (); Thread.Sleep (2000); System.out.println (th.getFlag ()); }} class ThreadTest implementiert Runnable {// Wenn ein Thread auf eine Variable zugreift, lädt er ihn in den entsprechenden Thread -Stapel. Bei jeder Operation müssen die neuesten Daten im Speicher privates volatiles booleaner Stoppflag erhalten. @Override public void run () {int i = 0; while (! Stoppflag) {i ++; System.out.println ("=="+thread.currentThread (). GetName ()); } System.out.println ("Thread Finish:"+i); } public void ChangeFlag () {this.stopflag = true; System.out.println (Thread.currentThread (). GetName ()+"*********"); } public boolean getFlag () {return stoppflag; }} Wenn der obige Code entfernt wird, wird er weiterhin in einer toten Schleife ausgeführt.
Aber volatil kann die Synchronisation der Gewinde nicht garantieren
z.B:
public class threadsave implements runnable {static threadsave sync = new threadsave (); statische volatile int j = 0; // lock lock = new Reentrantlock (); public void Inscane () {// lock.lock (); für (int i = 0; i <10000000; i ++) {j ++; } // lock.unlock (); } @Override public void run () {Inscane (); } public static void main (String [] args) löst InterruptedException aus {Thread t1 = neuer Thread (sync); Thread T2 = neuer Thread (Synchronisierung); t1.start (); t2.Start (); t1.join (); t2.join (); System.out.println (j); }} Das Ergebnis der Ausführung gemäß dem obigen Code wird nicht erwartet, dass 20000000.
Denn für Variablen, die durch volatile geändert werden, stellt die virtuelle JVM -Maschine nur sicher, dass der von dem Hauptspeicher zum Fadenspeicher geladene Wert der neueste ist.
Wenn beispielsweise Thread 1 und Thread 2 Thread Stack und Hauptspeicher lesen und laden und feststellen, dass der Wert der Anzahl im Hauptspeicher 5 beträgt, wird der neueste Wert geladen. Nachdem Thread 1 Heap -Anzahl geändert wurde, wird er in den Hauptspeicher geschrieben, und die Zählvariable im Hauptspeicher wird 6;
Da Thread 2 bereits Lese- und Ladevorgänge durchgeführt hat, wird nach der Durchführung des Vorgangs auch der variable Wert der Hauptspeicherzahl auf 6 aktualisiert.
Dies führt dazu, dass die Parallelität nach zwei Threads mit dem flüchtigen Schlüsselwort rechtzeitig geändert wurde.
Zusammenfassend:
Volatile stellt nur sicher, dass der Thread eine Aktion ausübt, die überprüft, ob der variable Wert des aktuellen Threadstapels dem Datenwert im Hauptspeicher entspricht, das ist alles. Lock oder Synchronized stellt sicher, dass nur ein einzelner Thread in einem bestimmten Zeitpunkt in die Methode eintritt, wodurch die Sicherheit der Gewinde gewährleistet ist.
Wenn also mehrere Threads eine flüchtige Variable ändern, gibt es keine tatsächliche logische Bedeutung. Wenn ein Thread den variablen Wert anderer Threads ändert, die von der Änderung abhängen, ist er zu diesem Zeitpunkt nützlich.
Das Obige dreht sich alles um diesen Artikel, ich hoffe, es wird für das Lernen aller hilfreich sein.