In Java werden das synchronisierte Schlüsselwort und die Sperreenschloss verwendet, um die gleichzeitige Zugriffskontrolle von Ressourcen zu realisieren. Nur einzigartige Themen dürfen in den kritischen Bereich eintreten, um auf Ressourcen zuzugreifen (mit Ausnahme von Lesen von Sperrs). Der Hauptzweck dieser Unterkontrolle besteht darin, das Problem der Datenkonsistenz zu lösen, die durch mehrere Threads gleichzeitig mit derselben Ressource verursacht werden. In einem anderen Szenario enthält eine Ressource mehrere Kopien zur gleichzeitigen Verwendung, z. B. mehrere Drucker im Druckerraum und mehrere Gruben zur gleichen Zeit. In diesem Fall bietet Java eine weitere gleichzeitige Zugriffskontrolle - die gleichzeitige Zugriffskontrolle für mehrere Kopien der Ressource, und das heute verwendete Semaphor ist eines davon.
Java kann potenzielle Sicherheitsprobleme in unserem System auf die schnellste Weise durch Codesimulation erkennen. Hier werden Semaphore (Semaphore) und Countdownlatch (Sperren) zur Simulation mit ExecutorService (Thread Pool) verwendet. Die Haupteinführung lautet wie folgt:
1. Semaphor
Diese Klasse wird nach JDK 1.5 bereitgestellt
Semaphore ist ein zählbasiertes Semaphor. Es kann einen Schwellenwert festlegen, basierend darauf konkurrieren mehrere Threads, um das Lizenzsignal zu erhalten und es nach der Erstellung ihrer eigenen Anwendung zurückzugeben. Nachdem der Schwellenwert überschritten wird, wird die Anwendung des Threads auf das Lizenzsignal blockiert. Semaphor kann verwendet werden, um einige Objektpools, Ressourcenpools usw. zu erstellen, z. B. Datenbankverbindungspools. Wir können auch ein Semaphor mit einer Anzahl von 1 erstellen, wobei wir es als Mechanismus verwenden, der den Mutex -Sperren ähnelt. Dies wird auch als binäres Semaphor bezeichnet, was auf zwei Mutex -Zustände hinweist.
2. Countdownlatch
Diese Klasse wird nach JDK 1.5 bereitgestellt.
Die Countdownlatch -Klasse kann einen Thread warten lassen, bis andere Threads vor der Ausführung ihre jeweiligen Arbeiten abschließen. Der Haupt -Thread der Anwendung möchte beispielsweise ausführen, nachdem der Thread, der für den Start des Framework -Dienstes verantwortlich ist, alle Framework -Dienste gestartet hat.
Countdownlatch wird über einen Zähler implementiert, und der Anfangswert des Zählers ist die Anzahl der Threads. Immer wenn ein Thread seine eigene Aufgabe erledigt, wird der Zählerwert durch 1. Wenn der Zählerwert 0 erreicht, bedeutet dies, dass alle Threads die Aufgabe abgeschlossen haben, und dann können die auf der Sperre warten, die Ausführung der Aufgabe wieder aufnehmen.
Wie in der Abbildung unten gezeigt:
Die beiden oben genannten Klassen können in Kombination verwendet werden, um den Effekt der Simulation einer hohen Parallelität zu erreichen. Der folgende Code wird verwendet, um ein Beispiel zu geben:
Paketmodule; import java.util.concurrent.countdownlatch; import Java.util.concurrent // Anzahl der gleichzeitig ausgeführten Threads gleichzeitig public static int threadTotal = 200; public static int count = 0; public static void main (String [] args) löst eine Ausnahme aus {ExecutorService ExecutorService = Executors.NewCachedThreadpool (); // Semiconductor, verwendet, um die Anzahl der gleichzeitigen Threads hier endgültig Semaphor Semaphore = New Semaphor (ThreadTotal) zu steuern; // Verriegelung, die die Abnahme des Zählers endgültig Countdownlatch Countdownlatch = neuer Countdownlatch (ClientTotal) realisieren kann; für (int i = 0; i <clientTotal; i ++) {ExecutorService.execute (() -> {try {// diese Methode ausführen, um die Ausführungsgenehmigung zu erhalten. Wenn die Gesamtzahl der unveröffentlichten Lizenzen nicht überschreitet, überschreitet 200, // Pass, ansonsten die Thread -Blöcke und Warten, bis die Lizenz erhalten wird. } catch (Ausnahme e) {//log.Eror("Exception ", e); } Countdownlatch.await (); // Thread -Blöcke, und der Block wird erst freigegeben, wenn der Sperrwert 0 beträgt. Führen Sie den Ausführungsbereich weiterhin aus. log.info ("count: {}", count); } private static void add () {count ++; }}Wie in der obigen Methode gezeigt, werden 5000 Anfragen simuliert und 200 gleichzeitige Operationen gleichzeitig bis zu 200 gleichzeitige Operationen. Beobachten Sie die Endergebnisse und stellen Sie fest, dass die Ergebnisse für jedes Mal unterschiedlich sind und mit den Erwartungen unvereinbar sind. Das Ergebnis ist wie folgt:
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 4997
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 4995
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 4998
Abschließende Schlussfolgerung: Die Methode hinzufügen ist nicht mit Thread-Sicherheit
Wenn Sie dann die Gewindesicherheit der Methode hinzufügen, ändern Sie die Methode hinzufügen wie folgt:
private static void add () {count.incrementandget ();}Die Ausführungsergebnisse sind wie folgt:
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
22: 18: 26.449 [Haupt] Info -Module.CountExample - Graf: 5000
Endgültige Schlussfolgerung: Die modifizierte Methode-Thread-Safe für die Methode hinzufügen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.