Viele Freunde haben vielleicht von dem Keyword Volatile gehört und haben es möglicherweise verwendet. Vor Java 5 war es ein kontroverses Schlüsselwort, da es häufig zu unerwarteten Ergebnissen führte. Erst nachdem Java 5 das volatile Schlüsselwort zurückgeführt hat, hat seine Vitalität wiedererlangt.
Die Funktion des volatilen Schlüsselworts besteht darin, alle Threads im System für die durch das Schlüsselwort modifizierten Variablen sichtbar zu machen, und kann den Arbeitsspeicher des Threads aus zwischengespeicherten Variablen untersagen, die durch das Volatile geändert werden.
Volatile 2 Nutzungsszenarien:
1. Sichtbarkeit: Java bietet volatile Schlüsselwörter, um die Sichtbarkeit zu gewährleisten.
Wenn eine gemeinsam genutzte Variable durch volatile geändert wird, stellt sie sicher, dass der geänderte Wert sofort auf den Hauptspeicher aktualisiert wird. Wenn andere Threads ihn lesen müssen, wird der neue Wert im Speicher gelesen.
Stammhelme gemeinsame Variablen können jedoch die Sichtbarkeit nicht garantieren, da es ungewiss ist, wann die normale gemeinsam genutzte Variable nach der Änderung in den Hauptspeicher geschrieben wird. Wenn andere Themen es lesen, kann der ursprüngliche alte Wert noch im Speicher liegen, sodass die Sichtbarkeit nicht garantiert werden kann.
Darüber hinaus kann synchronisiert und sperren auch die Sichtbarkeit sicherstellen. Synchronisierte und Sperren können sicherstellen, dass nur ein Thread gleichzeitig die Sperre erfasst und den Synchronisierungscode ausführt. Vor der Veröffentlichung der Sperre wird die Änderung der Variablen zum Hauptspeicher aktualisiert. Daher kann die Sichtbarkeit garantiert werden.
Schauen wir uns zuerst einen Code an. Wenn Thread 1 zuerst ausgeführt wird und Thread 2 später ausgeführt wird:
// Thread 1Boolean stop = false; while (! stop) {dosomething ();} // Thread 2stop = true;Dieser Code ist ein sehr typischer Code, und viele Personen können diese Markup -Methode bei der Unterbrechung von Threads verwenden. Aber wird dieser Code in der Tat ganz richtig ausgeführt? Wird der Thread unterbrochen? Nicht unbedingt. Vielleicht kann dieser Code die meiste Zeit Threads unterbrechen, aber er kann auch dazu führen, dass der Thread nicht unterbrochen wird (obwohl diese Möglichkeit sehr klein ist, wird dies nach diesem Fall eine tote Schleife verursachen).
Lassen Sie uns erklären, warum dieser Code dazu führen kann, dass der Thread nicht unterbricht. Wie bereits erläutert, hat jeder Thread während des Betriebs seinen eigenen Arbeitsspeicher. Wenn Thread 1 ausgeführt wird, kopiert er den Wert der Stoppvariablen und stellt ihn in seinen eigenen Arbeitsspeicher.
Wenn Thread 2 dann den Wert der Stoppvariablen ändert, aber keine Zeit hatte, ihn in den Hauptspeicher zu schreiben, geht Thread 2 für andere Dinge, und Thread 1 weiß nicht über die Änderungen von Thread 2 an der Stoppvariablen, sodass es weiterhin schleifen wird.
Aber nach dem Modifizieren mit volatilen wird es anders:
Erstens: Die Verwendung des volatilen Schlüsselworts erzwingt den geänderten Wert sofort in den Hauptspeicher.
Zweitens: Wenn Sie das volatile Schlüsselwort verwenden, ist bei Thread 2 die Cache -Zeile des Cache -Variablen -Stopps im Arbeitsspeicher des Thread 1 ungültig (wenn es in der Hardwareschicht reflektiert wird, ist die entsprechende Cache -Zeile im L1- oder L2 -Cache des CPU ungültig).
Drittens: Da die Cache -Zeile der Cache -Variablen im Arbeitsspeicher von Thread 1 ungültig ist, wird Thread 1 im Hauptspeicher gelesen, wenn der Wert des Variablen -Stopps erneut liest.
Wenn Thread 2 dann den Stoppwert ändert (natürlich gibt es 2 Operationen hier, wobei der Wert im Arbeitsspeicher von Thread 2 geändert und dann den geänderten Wert in den Speicher geschrieben wird), ist die Cache -Zeile der Cache -Variablen -Stop -Stop im Arbeitsspeicher des Thread 1 ungültig. Wenn Thread 1 liest, wird festgestellt, dass seine Cache -Zeile ungültig ist. Es wartet, bis die entsprechende Hauptspeicheradresse der Cache -Zeile aktualisiert wird, und lesen dann den neuesten Wert im entsprechenden Hauptspeicher.
Was dann Thread 1 liest, ist der neueste korrekte Wert.
2. Sorge Ordnung
volatile boolean initiated = false; // Thread 1: context = loadContext (); initiiert = wahr; // Thread 2: while (! Inited) {sleep ()} dosomethingwithconfig (Kontext);Stellen Sie sicher, dass der Kontext initialisiert wurde.
3. Verdoppelungsprüfung
Klasse Singleton {private volatile statische Singleton Instance = null; private Singleton () {} public static singleton getInstance () {if (Instance == null) {synchronized (Singleton.class) {if (Instance == null) instance = new Singleton ();Das obige ist eine detaillierte Erklärung der Rolle und Verwendung 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!