Heim  >  Artikel  >  Java  >  Der Unterschied und Zusammenhang zwischen synchronisiert und flüchtig in Java

Der Unterschied und Zusammenhang zwischen synchronisiert und flüchtig in Java

黄舟
黄舟Original
2017-10-19 09:57:451561Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen über den Unterschied und die Verbindung zwischen flüchtig und synchronisiert in Java vor. Ich hoffe, dass dieser Artikel jedem helfen kann, diesen Teil des Inhalts zu verstehen

Der Unterschied und Zusammenhang zwischen Volatile und Synchronized in Java

Dies ist möglicherweise der beste Artikel, der die Auswirkungen von Volatile und Synchronized vergleicht. Volatile ist ein Variablenmodifikator und synchronisiert ist ein Methoden- oder Blockmodifikator. Daher verwenden wir diese beiden Schlüsselwörter, um drei einfache Möglichkeiten für den Zugriff auf Variablen anzugeben:


  int i1;            int geti1() {return i1;}
volatile int i2;            int geti2() {return i2;}
   int i3;     synchronized int geti3() {return i3;}

geti1() ruft den Wert sofort im aktuellen Thread ab. Der Wert im i1-Variable. Ein Thread kann eine lokale Kopie einer Variablen erhalten, und der Wert der erhaltenen Variablen ist nicht unbedingt derselbe wie der von anderen Threads erhaltene Wert. Insbesondere wenn andere Threads den Wert von i1 ändern, kann sich der vom aktuellen Thread erhaltene Wert von i1 vom geänderten Wert unterscheiden. Tatsächlich verfügt Java über einen Hauptspeichermechanismus, der einen Hauptspeicher verwendet, um den aktuell korrekten Wert der Variablen zu speichern. Threads kopieren die Werte von Variablen in ihren eigenen unabhängigen Speicher, und die Speicherkopien dieser Threads können sich von den Werten im Hauptspeicher unterscheiden. In der Praxis kann es also vorkommen, dass der Wert von i1 im Hauptspeicher 1 ist und sowohl Thread 1 als auch Thread 2 i1 geändert haben, der aktualisierte Wert jedoch nicht zurück in den Hauptspeicher oder andere Threads übertragen wurde im Thread sein Der Wert von i1 in Thread 1 ist 2, aber der Wert von i1 in Thread 2 ist 3.

Andererseits kann geti2() den Wert von i2 effektiv aus dem Hauptspeicher abrufen. Eine flüchtige Variable erlaubt einem Thread nicht, den Wert der Variablen aus dem Hauptspeicher in seinen eigenen Speicherplatz zu kopieren. Daher erhält eine als flüchtig deklarierte Variable Daten synchron in allen Threads. Unabhängig davon, ob Sie die Variable in einem Thread ändern, erhalten andere Threads sofort das gleiche Ergebnis. Da es für Threads effizienter ist, auf ihre eigenen Datenkopien zuzugreifen oder diese zu ändern, verbrauchen flüchtige Typvariablen einen Teil der Leistung.
Wenn also flüchtige Variablen bereits Daten zwischen Threads synchronisieren können, wofür werden Synchronisierungen verwendet? Es gibt zwei Unterschiede zwischen den beiden. Erstens: Synchronisiert erwirbt und gibt Sperren frei, die vom Listener gesteuert werden. Wenn beide Threads einen Listener verwenden (d. h. dieselbe Objektsperre), kann der Listener jeweils nur einen Thread zwingen, den Codeblock zu verarbeiten synchron. Darüber hinaus kann synchronisiert auch den Speicher synchronisieren. In der Praxis synchronisiert synchronisiert den gesamten Thread-Speicher mit dem Hauptspeicher. Der Ausführungsprozess von geti3() ist also wie folgt:

1 Der Thread erhält die Sperre des Objekts vom Listener. (Hier wird davon ausgegangen, dass der Listener nicht gesperrt ist, andernfalls kann der Thread die Objektsperre nicht erhalten, bis der Listener entsperrt ist)

2. Der Thread-Speicher aktualisiert alle Variablen, was bedeutet, dass er liest Die Variablen im Hauptspeicher sorgen dafür, dass Ihre eigenen Variablen gültig sind. (Die JVM verwendet ein „Dirty“-Flag, um den Prozess zu optimieren, sodass nur Variablen mit dem „Dirty“-Flag aktualisiert werden. Weitere Informationen finden Sie in Abschnitt 17.9 der JAVA-Spezifikation.)

3 Block wird ausgeführt (In diesem Beispiel wird der Rückgabewert auf den aktuellen Wert von i3 gesetzt, der gerade aus dem Hauptspeicher zurückgesetzt wurde.)

Alle Änderungen an den Variablen werden in den Hauptspeicher zurückgeschrieben . In diesem Beispiel gibt es jedoch keine Änderung an geti3().

5. Der Thread gibt die Sperre des Objekts für den Listener frei.

Volatil kann also nur den Wert einer Variablen zwischen Thread-Speicher und Hauptspeicher synchronisieren, während synchronisiert den Wert aller Variablen zwischen Thread-Speicher und Hauptspeicher synchronisiert und dies durch Sperren und Freigeben des Listeners erreichen kann Das. Synchronisiert ist offensichtlich leistungsintensiver als volatil.

Über den Unterschied zwischen den beiden

1. Volatile teilt dem JVM im Wesentlichen mit, dass der Wert der aktuellen Variablen im Register (Arbeitsspeicher) unsicher ist Es muss aus dem Hauptspeicher gelesen werden; synchronisiert sperrt nur der aktuelle Thread und andere Threads werden blockiert.

2.volatile kann nur auf Variablenebene verwendet werden; synchronisiert kann auf Variablen-, Methoden- und Klassenebene verwendet werden

3.volatile kann verwendet werden nur implementiert werden Die Änderungssichtbarkeit von Variablen kann die Atomizität nicht garantieren; synchronisiert kann die Änderungssichtbarkeit und Atomizität von Variablen garantieren

4.

5. Variablen, die als „volatil“ gekennzeichnet sind, werden vom Compiler nicht optimiert; Variablen, die als „synchronisiert“ markiert sind, können vom Compiler optimiert werden

Die Gründe für den roten Schriftteil lauten wie folgt:

Wenn Thread A die Variable ändert, bevor sie endet, kann ein anderer Thread B den geänderten Wert sehen und die Variable ändern, ohne darauf zu warten, dass A die Sperre aufhebt, weil der flüchtige Variable freigeschaltet

Das obige ist der detaillierte Inhalt vonDer Unterschied und Zusammenhang zwischen synchronisiert und flüchtig in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn