CountDownLatch は Java 同時実行パッケージの非常に実用的なツール クラスで、スレッド間の同期とコラボレーションを実現するのに役立ちます。 CountDownLatch の中心となるアイデアは、カウンターを通じてスレッドの実行順序を制御することです。カウンタ値が 0 に下がると、待機中のすべてのスレッドが起動され、次の操作の実行が開始されます。
Java では、CountDownLatch の実装は AbstractQueuedSynchronizer クラスに基づいています。 AbstractQueuedSynchronizer は非常に重要なシンクロナイザーであり、Semaphore、ReentrantLock、ReadWriteLock など、Java の多くの同時実行クラスがこれに基づいて実装されています。
CountDownLatch のコア実装クラスは Sync で、AbstractQueuedSynchronizer から継承された内部クラスです。以下は、Sync クラスのソース コードです:
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; } } }
Sync クラスには 3 つの重要なメソッドがあります:
tryAcquireShared(int happens): の取得を試みます。 lock は、カウンタの値が 0 に等しい場合 (すべてのスレッドが実行を完了したことを示します)、1 を返します。それ以外の場合は、ロックの取得に失敗したことを示す -1 を返します。
tryReleaseShared(int releases): ロックを解除し、カウンタ値を 1 減算し、1 減算した後のカウンタ値を返します。カウンタの値が 0 まで減少した場合は、すべてのスレッドが実行を完了して true を返し、それ以外の場合は false を返します。
getCount(): 現在のカウンター値を返します。
tryAcquireShared() メソッドは CountDownLatch のキーであり、ロックの取得を試みます。カウンタの値が 0 に等しい場合は、すべてのスレッドが実行を完了したことを意味し、ロックの取得が成功したことを示す 1 が返されます。それ以外の場合は、ロックの取得が失敗したことを示す -1 が返されます。ここでは、AbstractQueuedSynchronizer クラスの基本メソッド、つまり、シンクロナイザーのステータスを取得するために使用される getState() メソッドが使用されます。
tryReleaseShared() メソッドは、ロックを解放し、カウンタ値を 1 減算し、1 減算した後のカウンタ値を返すために使用されます。カウンタの値が 0 まで減少した場合は、すべてのスレッドが実行を完了して true を返し、それ以外の場合は false を返します。ここでは、AtomicInteger クラスの基本メソッド、つまり CompareAndSetState() メソッドが使用されます。これは、シンクロナイザーのステータスを比較して設定するために使用されます。
CountDownLatch の動作原理は非常に単純で、カウンターを通じてスレッドの実行順序を制御します。カウンタ値が 0 に下がると、待機中のすべてのスレッドが起動され、次の操作の実行が開始されます。
CountDownLatch は、1 つ以上のスレッドが他のスレッドによる操作の完了を待ってから続行できるようにするマルチスレッド コラボレーション ツール クラスです。 CountDownLatch はカウンタを持っており、カウンタの値が 0 になると待機中のスレッドが起動されます。 CountDownLatch の使用は非常に簡単で、主に await() と countDown() の 2 つのメソッドが含まれます。
await() メソッド: このメソッドは、カウンター値が 0 になるまで現在のスレッドをブロックします。
countDown() メソッド: このメソッドは、カウンター値を 1 ずつデクリメントします。
以下は簡単なサンプル コードです:
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("所有任务执行完毕..."); } }
このサンプル コードでは、CountDownLatch オブジェクトを作成し、カウンターを 3 に初期化します。次に 3 つのスレッドが作成され、各スレッドがタスクを実行し、タスクが完了するとカウンターが 1 減算されます。最後に、メイン スレッドで latch.await() メソッドを呼び出し、すべてのタスクが完了するのを待ちます。
CountDownLatch の実装原理は、AbstractQueuedSynchronizer クラスに基づいています。 await() メソッドを呼び出すと、スレッドはロックの取得を試みますが、カウンタ値が 0 でない場合、ロックの取得は失敗し、スレッドは同期キューに追加されてブロックされます。 countDown() メソッドを呼び出すと、カウンタ値が 1 減ります。カウンタ値が 0 に減れば、すべてのスレッドの実行が完了したことを意味します。この時点で、同期キュー内のスレッドが起動され、次の操作を続行します。
具体的には、Sync クラスでは、tryAcquireShared(intacquires) メソッドがロックの取得を試みます。カウンターの値が 0 に等しい場合は、すべてのスレッドが実行を完了したことを意味し、1 を返します。それ以外の場合は、ロックの取得に失敗したことを意味する -1 を返します。 tryReleaseShared(int releases) メソッドは、ロックを解放し、カウンタ値を 1 減算し、1 減算した後のカウンタ値を返すために使用されます。カウンタの値が 0 まで減少した場合は、すべてのスレッドが実行を完了して true を返し、それ以外の場合は false を返します。
CountDownLatch は、スレッド間の同期とコラボレーションを実現するのに役立つ非常に実用的なツール クラスです。以下に、CountDownLatch の一般的なアプリケーション シナリオをいくつか紹介します。
複数のスレッドの完了を待機: 実行する必要があるスレッドが複数あるが、すべてのスレッドが完了するまで待機する必要がある場合。これは、CountDownLatch を使用して実現できます。 CountDownLatch オブジェクトを作成し、カウンタ値をスレッド数に初期化できます。各スレッドの実行が完了したら、countDown() メソッドを呼び出してカウンタを 1 ずつデクリメントします。最後に、メイン スレッドで await() メソッドを呼び出し、すべてのスレッドの実行が完了するのを待ちます。
スレッドの実行順序を制御する: 特定の順序で実行する必要があるスレッドが複数ある場合は、CountDownLatch を使用してこれを実現できます。複数の CountDownLatch オブジェクトを作成できます。各オブジェクトのカウンタ値は 1 で、1 つのスレッドのみが実行できることを示します。スレッドの実行が完了したら、次の CountDownLatch オブジェクトの countDown() メソッドを呼び出して、次のスレッドを起動します。
外部イベントの発生を待つ: ネットワーク接続の確立やファイルの読み取りの完了など、外部イベントの発生を待つ必要がある場合は、これを実現するには、CountDownLatch を使用できます。メインスレッドで CountDownLatch オブジェクトを作成し、カウンター値を 1 に初期化して、別のスレッドで外部イベントが発生するのを待ちます。外部イベントが発生すると、CountDownLatch オブジェクトの countDown() メソッドを呼び出して、メイン スレッドを起動して実行を継続します。
同時スレッドの数を制御する: 同時スレッドの数を制御する必要がある場合は、CountDownLatch を使用してそれを実現できます。 CountDownLatch オブジェクトを作成し、カウンタ値をスレッド数に初期化できます。各スレッドの実行が完了したら、countDown() メソッドを呼び出してカウンタを 1 ずつデクリメントします。スレッドが他のスレッドの実行を完了するのを待つ必要がある場合、await() メソッドを呼び出してカウンター値が 0 になるのを待つことができます。
以上がJava Concurrency Toolkit の CountDownLatch クラスを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。