CountDownLatch ist eine sehr praktische Toolklasse im Java-Parallelitätspaket. Sie kann uns dabei helfen, Synchronisierung und Zusammenarbeit zwischen Threads zu erreichen. Die Kernidee von CountDownLatch besteht darin, die Ausführungsreihenfolge von Threads durch Zähler zu steuern. Wenn der Zählerwert auf 0 fällt, werden alle wartenden Threads geweckt und beginnen dann mit der Ausführung der nächsten Operation.
In Java basiert die Implementierung von CountDownLatch auf der AbstractQueuedSynchronizer-Klasse. AbstractQueuedSynchronizer ist ein sehr wichtiger Synchronisierer. Viele Parallelitätsklassen in Java werden darauf basierend implementiert, z. B. Semaphore, ReentrantLock, ReadWriteLock usw.
Die Kernimplementierungsklasse von CountDownLatch ist Sync, eine interne Klasse, die von AbstractQueuedSynchronizer geerbt wurde. Das Folgende ist der Quellcode der Sync-Klasse:
private static final class Sync extends AbstractQueuedSynchronizer { Sync(int count) { setState(count); } int getCount() { return getState(); } protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } }
Es gibt drei wichtige Methoden in der Sync-Klasse:
tryAcquireShared(int acquires): Versuchen Sie, die Sperre zu erhalten, wenn der Zählerwert gleich 0 ist bedeutet, dass alle Threads die Ausführung abgeschlossen haben und 1 zurückgegeben wird, andernfalls wird -1 zurückgegeben, was darauf hinweist, dass die Sperre nicht erhalten werden konnte.
tryReleaseShared(int releases): Heben Sie die Sperre auf, verringern Sie den Zählerwert um 1 und geben Sie den Zählerwert nach der Verringerung um 1 zurück. Wenn der Wert des Zählers auf 0 sinkt, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben und true zurückgibt, andernfalls false.
getCount(): Gibt den aktuellen Zählerwert zurück.
tryAcquireShared()-Methode ist der Schlüssel zu CountDownLatch, sie wird versuchen, die Sperre zu erlangen. Wenn der Wert des Zählers gleich 0 ist, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben. 1 kann zurückgegeben werden, was angibt, dass die Sperrenerfassung erfolgreich war. Andernfalls wird -1 zurückgegeben, was angibt, dass die Sperrenerfassung fehlgeschlagen ist. Hier wird die grundlegende Methode der AbstractQueuedSynchronizer-Klasse verwendet, nämlich die Methode getState(), mit der der Status des Synchronizers ermittelt wird. Die Methode
tryReleaseShared() wird verwendet, um die Sperre aufzuheben, den Zählerwert um 1 zu dekrementieren und den Zählerwert nach der Dekrementierung um 1 zurückzugeben. Wenn der Wert des Zählers auf 0 sinkt, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben und true zurückgibt, andernfalls false. Hier wird die grundlegende Methode der AtomicInteger-Klasse verwendet, nämlich die Methode CompareAndSetState(), mit der der Status des Synchronizers verglichen und festgelegt wird.
Das Funktionsprinzip von CountDownLatch ist sehr einfach. Es verwendet einen Zähler, um die Ausführungsreihenfolge von Threads zu steuern. Wenn der Zählerwert auf 0 fällt, werden alle wartenden Threads geweckt und beginnen dann mit der Ausführung der nächsten Operation.
CountDownLatch ist eine Multithread-Collaboration-Tool-Klasse, die es einem oder mehreren Threads ermöglicht, darauf zu warten, dass andere Threads einen Vorgang abschließen, bevor sie mit der Ausführung fortfahren. CountDownLatch verfügt über einen Zähler. Wenn der Zählerwert 0 wird, wird der wartende Thread geweckt. Die Verwendung von CountDownLatch ist sehr einfach und umfasst hauptsächlich zwei Methoden: waiting () und countDown ().
await()-Methode: Diese Methode blockiert den aktuellen Thread, bis der Zählerwert 0 wird.
countDown()-Methode: Diese Methode verringert den Zählerwert um 1.
Hier ist ein einfacher Beispielcode:
public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { final int count = 3; final CountDownLatch latch = new CountDownLatch(count); for (int i = 0; i < count; i++) { new Thread(() -> { // 线程执行任务 System.out.println(Thread.currentThread().getName() + " 执行任务..."); // 任务执行完毕,计数器减1 latch.countDown(); }).start(); } // 等待所有任务执行完毕 latch.await(); System.out.println("所有任务执行完毕..."); } }
In diesem Beispielcode erstellen wir ein CountDownLatch-Objekt und initialisieren den Zähler auf 3. Dann werden 3 Threads erstellt, jeder Thread führt eine Aufgabe aus. Nach Abschluss der Aufgabe wird der Zähler um 1 verringert. Rufen Sie abschließend die Methode „latch.await()“ im Hauptthread auf, um auf den Abschluss aller Aufgaben zu warten.
Das Implementierungsprinzip von CountDownLatch basiert auf der AbstractQueuedSynchronizer-Klasse. Wenn wir die Methode „await()“ aufrufen, versucht der Thread, die Sperre zu erhalten. Wenn der Zählerwert nicht 0 ist, schlägt die Sperrenerfassung fehl und der Thread wird zur Synchronisationswarteschlange hinzugefügt und blockiert. Wenn wir die countDown()-Methode aufrufen, wird der Zählerwert um 1 reduziert. Wenn der Zählerwert auf 0 reduziert wird, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben. Zu diesem Zeitpunkt werden die Threads in der Synchronisationswarteschlange aktiviert und aktiviert Fahren Sie mit der nächsten Operation fort.
In der Sync-Klasse versucht die Methode tryAcquireShared(int acquires), die Sperre zu erhalten. Wenn der Zählerwert gleich 0 ist, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben, andernfalls wird - zurückgegeben. Es wird 1 zurückgegeben, was darauf hinweist, dass die Sperrenerfassung fehlgeschlagen ist. Die Methode tryReleaseShared(int releases) wird verwendet, um die Sperre aufzuheben, den Zählerwert um 1 zu verringern und den Zählerwert nach der Dekrementierung um 1 zurückzugeben. Wenn der Wert des Zählers auf 0 sinkt, bedeutet dies, dass alle Threads die Ausführung abgeschlossen haben und „true“ zurückgibt, andernfalls wird „false“ zurückgegeben.
CountDownLatch ist eine sehr praktische Toolklasse, die uns helfen kann, Synchronisation und Zusammenarbeit zwischen Threads zu erreichen. Hier sind einige häufige Anwendungsszenarien von CountDownLatch:
Warten, bis mehrere Threads die Ausführung abgeschlossen haben: Wenn mehrere Threads ausgeführt werden müssen, Sie jedoch warten müssen, bis alle Threads die Ausführung abgeschlossen haben, bevor Sie mit dem nächsten Schritt fortfahren, müssen Sie kann CountDownLatch verwenden, um dies zu erreichen. Wir können ein CountDownLatch-Objekt erstellen und den Zählerwert auf die Anzahl der Threads initialisieren. Nachdem jeder Thread die Ausführung abgeschlossen hat, rufen Sie die Methode countDown() auf, um den Zähler um 1 zu verringern. Rufen Sie abschließend die Methode „await()“ im Hauptthread auf, um zu warten, bis alle Threads die Ausführung abgeschlossen haben.
Steuern Sie die Ausführungsreihenfolge von Threads: Wenn mehrere Threads in einer bestimmten Reihenfolge ausgeführt werden müssen, können Sie CountDownLatch verwenden, um dies zu erreichen. Wir können mehrere CountDownLatch-Objekte erstellen, und der Zählerwert jedes Objekts ist 1, was darauf hinweist, dass nur ein Thread ausgeführt werden kann. Nachdem der Thread die Ausführung abgeschlossen hat, rufen Sie die countDown()-Methode des nächsten CountDownLatch-Objekts auf, um den nächsten Thread zu aktivieren.
Warten auf das Eintreten eines externen Ereignisses: Wenn wir auf das Eintreten eines externen Ereignisses warten müssen, z. B. auf den Aufbau einer Netzwerkverbindung oder den Abschluss eines Lesevorgangs Datei können wir CountDownLatch zur Implementierung verwenden. Wir können ein CountDownLatch-Objekt im Hauptthread erstellen, den Zählerwert auf 1 initialisieren und dann darauf warten, dass das externe Ereignis in einem anderen Thread auftritt. Wenn ein externes Ereignis auftritt, rufen Sie die countDown()-Methode des CountDownLatch-Objekts auf, um den Hauptthread zu aktivieren und die Ausführung fortzusetzen.
Kontrollieren Sie die Anzahl gleichzeitiger Threads: Wenn wir die Anzahl gleichzeitiger Threads steuern müssen, können wir CountDownLatch verwenden, um dies zu erreichen. Wir können ein CountDownLatch-Objekt erstellen und den Zählerwert auf die Anzahl der Threads initialisieren. Nachdem jeder Thread die Ausführung abgeschlossen hat, rufen Sie die Methode countDown() auf, um den Zähler um 1 zu verringern. Wenn ein Thread darauf warten muss, dass andere Threads die Ausführung abschließen, kann er die Methode „await()“ aufrufen, um darauf zu warten, dass der Zählerwert 0 wird.
Das obige ist der detaillierte Inhalt vonWie verwende ich die CountDownLatch-Klasse aus dem Java Concurrency Toolkit?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!