Dieser Artikel bietet Ihnen eine kurze Einführung in die Java-Multithreading-Schlüsselwörter „Volatil“, „Lock“ und „Synchronisiert“. Ich hoffe, dass er Ihnen weiterhilft .
1. Flüchtig
Speichersemantik des flüchtigen Schreibens und des flüchtigen Lesens:
Thread A schreibt eine flüchtige Variable, bei der es sich im Wesentlichen um das Schreiben von Thread A in den Speicher handelt wird als nächstes gelesen. Ein Thread dieser flüchtigen Variablen hat eine Nachricht ausgegeben (die die gemeinsam genutzte Variable geändert hat). Wenn Thread B eine flüchtige Variable liest, empfängt Thread B im Wesentlichen eine Nachricht, die von einem vorherigen Thread gesendet wurde (Änderungen an der gemeinsam genutzten Variablen vor dem Schreiben der flüchtigen Variablen). Thread A schreibt eine flüchtige Variable und dann liest Thread B die flüchtige Variable. Bei diesem Prozess sendet Thread A eine Nachricht über den Hauptspeicher an Thread B.
Speichersemantik der Sperrenfreigabe und des Sperrenerwerbs:
Thread A gibt eine Sperre frei. Im Wesentlichen sendet Thread A eine Nachricht an einen Thread, der die Sperre als nächstes erwerben wird (Thread A hat eine gemeinsame Sperre). (Variablenänderung)-Meldung. Thread B erwirbt eine Sperre Im Wesentlichen empfängt Thread B eine Nachricht, die von einem vorherigen Thread gesendet wurde (Änderungen an gemeinsam genutzten Variablen, bevor die Sperre aufgehoben wird). Thread A gibt die Sperre frei und dann erhält Thread B die Sperre. Bei diesem Prozess sendet Thread A im Wesentlichen eine Nachricht an Thread B über den Hauptspeicher.
Zusammenfassung: Die Rolle des Schlüsselworts volatile besteht darin, Variablen über mehrere Threads hinweg sichtbar (sichtbar) zu machen, aber volatile allein kann die Thread-Sicherheit nicht gewährleisten. Das Schlüsselwort volatile verfügt nicht über das synchronisierte Schlüsselwort.
2. lock
Lock ist eine Schnittstelle:
public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
lock(), tryLock(), tryLock(long time, TimeUnit unit) und lockInterruptously() werden verwendet das Schloss.
Die Methode unLock() wird verwendet, um die Sperre aufzuheben. Die tryLock()-Methode hat einen Rückgabewert, was bedeutet, dass sie verwendet wird, um zu versuchen, die Sperre zu erhalten. Wenn die Erfassung erfolgreich ist, gibt sie true zurück. Wenn die Erfassung fehlschlägt (d. h. die Sperre wurde von einem anderen Thread erworben). es gibt false zurück, was bedeutet, dass diese Methode egal ist, was sofort zurückgegeben wird. Sie werden nicht dort warten, wenn Sie das Schloss nicht bekommen. Die tryLock-Methode (lange Zeit, TimeUnit-Einheit) ähnelt der tryLock()-Methode, der Unterschied besteht jedoch darin, dass diese Methode eine bestimmte Zeit lang wartet, wenn sie die Sperre nicht innerhalb dieser Zeit erhalten kann limit, es wird false zurückgegeben. Gibt „true“ zurück, wenn die Sperre ursprünglich oder während der Wartezeit erhalten wurde. Die lockInterruptably()-Methode ist etwas Besonderes. Wenn der Thread über diese Methode eine Sperre erhält, kann er auf den Interrupt reagieren, dh den Wartezustand des Threads unterbrechen. Das heißt, wenn zwei Threads gleichzeitig eine Sperre über lock.lockInterruptably () erhalten möchten und Thread A zu diesem Zeitpunkt die Sperre erhält und Thread B nur wartet, ist dies die Methode threadB.interrupt() Wird für Thread B aufgerufen. Kann den Wartevorgang von Thread B unterbrechen.
Die Sperre kann während des Erwerbs der Sperre unterbrochen werden. lock kann versuchen, die Sperre zu erlangen, wenn die Sperre von einem anderen Thread gehalten wird, gibt sie false zurück und führt nicht dazu, dass der aktuelle Thread in den Ruhezustand versetzt wird. Wenn Lock versucht, die Sperre zu erhalten, übergibt es einen Zeitparameter. Wenn die Sperre nicht innerhalb dieses Zeitbereichs erworben wird, wird die Anforderung beendet. Durch die Synchronisierung wird die Sperre automatisch aufgehoben, die Sperre wird jedoch nicht automatisch aufgehoben. Hinweis: lock() kann verwendet werden, um einen Teil des Codes zu sperren, sodass anderer Code warten muss, bevor die Sperre aufgehoben wird. Es ist zu beachten, dass lock die Sperre nicht automatisch aufhebt, wie synchronisiert, daher muss sie in a platziert werden try-finally blockieren, um sicherzustellen, dass die Sperre aufgehoben wird.
Lock und synchronisiert haben die folgenden Unterschiede:
1) Lock ist eine Schnittstelle, während synchronisiert ein Schlüsselwort in Java ist und synchronisiert eine integrierte Sprachimplementierung ist
2) Wenn eine Ausnahme auftritt, gibt die Synchronisierung automatisch die vom Thread belegte Sperre frei, sodass kein Deadlock verursacht wird. Wenn eine Ausnahme auftritt, wird die Sperre wahrscheinlich nicht aktiv durch unLock () freigegeben Wenn Sie also Lock verwenden, müssen Sie die Sperre im „finally“-Block aufheben. 3) Lock kann es dem Thread ermöglichen, auf den Interrupt zu reagieren, synchronisiert jedoch nicht synchronisiert, der wartende Thread wartet ewig und kann nicht auf Unterbrechungen reagieren.
4) Über Lock können Sie feststellen, ob die Sperre erfolgreich erworben wurde, synchronisiert ist dies jedoch nicht.
5) Sperren können die Effizienz mehrerer Thread-Lesevorgänge verbessern. In Bezug auf die Leistung ist die Leistung der beiden fast gleich, wenn der Wettbewerb um Ressourcen nicht hart ist. Wenn der Wettbewerb um Ressourcen sehr hart ist (dh es gibt eine große Anzahl von Threads, die gleichzeitig konkurrieren). Die Leistung von Lock ist weitaus besser als die von synchronisiert. Daher sollte es bei der Verwendung entsprechend der entsprechenden Situation ausgewählt werden. ReentrantLock bedeutet „Wiedereintrittssperre“. Das Konzept der Wiedereintrittssperre wird im nächsten Abschnitt beschrieben. ReentrantLock ist die einzige Klasse, die die Lock-Schnittstelle implementiert, und ReentrantLock bietet weitere Methoden.
3. synchronisiert
1. Wenn zwei gleichzeitige Threads auf den synchronisierten (diesen) Synchronisationscodeblock im selben Objekt zugreifen, kann jeweils nur ein Thread ausgeführt werden. Ein anderer Thread muss warten, bis der aktuelle Thread die Ausführung dieses Codeblocks abgeschlossen hat, bevor er diesen Codeblock ausführen kann.
2. Wenn jedoch ein Thread auf einen synchronisierten (diesen) synchronisierten Codeblock des Objekts zugreift, kann ein anderer Thread immer noch auf den nicht synchronisierten (diesen) synchronisierten Codeblock im Objekt zugreifen.
3. Was besonders wichtig ist, ist, dass, wenn ein Thread auf einen synchronisierten (diesen) synchronisierten Codeblock des Objekts zugreift, andere Threads daran gehindert werden, auf alle anderen synchronisierten (diesen) synchronisierten Codeblöcke im Objekt zuzugreifen.
4. Das dritte Beispiel ist auch auf andere Synchronisationscodeblöcke anwendbar. Das heißt, wenn ein Thread auf einen synchronisierten (diesen) synchronisierten Codeblock eines Objekts zugreift, erhält er die Objektsperre dieses Objekts. Dadurch wird der Zugriff anderer Threads auf alle synchronisierten Codeteile des Objektobjekts vorübergehend blockiert. Geltungsbereich des synchronisierten Schlüsselworts: Innerhalb einer Objektinstanz kann synchronisiert aMethod(){} verhindern, dass mehrere Threads gleichzeitig auf die synchronisierte Methode dieses Objekts zugreifen (wenn ein Objekt über mehrere synchronisierte Methoden verfügt, solange ein Thread auf eine davon zugreift). die Methode der synchronisierten Methoden, andere Threads können nicht gleichzeitig auf eine synchronisierte Methode in diesem Objekt zugreifen). Zu diesem Zeitpunkt stören sich die synchronisierten Methoden verschiedener Objektinstanzen nicht gegenseitig. Mit anderen Worten, andere Threads können weiterhin gleichzeitig auf die synchronisierte Methode in einer anderen Objektinstanz derselben Klasse zugreifen. Synchronisiertes statisches aStaticMethod{} verhindert, dass mehrere Threads auf die synchronisierte statische Methode in dieser Klasse zugreifen gleichzeitig. Es funktioniert auf allen Objektinstanzen der Klasse.
Das obige ist der detaillierte Inhalt vonEine kurze Einführung in die Java-Multithreading-Schlüsselwörter „Volatil', „Lock' und „Synchronized'.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!