ホームページ  >  記事  >  Java  >  Java CountDownLatch カウンターと CyclicBarrier サイクル バリアを定義する方法

Java CountDownLatch カウンターと CyclicBarrier サイクル バリアを定義する方法

WBOY
WBOY転載
2023-05-21 18:25:14753ブラウズ

定義

CountDownLatch: 他のスレッドで実行されている一連の操作が完了するまで、1つまたは複数のスレッドが待機できるようにする同期支援機能。

CyclicBarrier: 一連のスレッドが互いに共通のバリア ポイントに到達するのを待機できるようにする同期支援機能。

上記は Oracle の公式定義です。簡単に言うと、

CountDownLatch: 他のスレッドで実行された一連の操作が完了するまで 1 つ以上のスレッドを待機できるようにするカウンター。

CyclicBarrier: サイクリック バリア。スレッドのグループが共通のバリア ポイントに到達するまで相互に待機できるようにします。

Difference

  • CountDownLatch は AQS (AbstractQueuedSynchronizer) のメンバーですが、CyclicBarrier はメンバーではありません。

  • CountDownLatch の使用シナリオでは、await() メソッドを呼び出す待機スレッドと、countDownl メソッドを呼び出す操作スレッドの 2 種類のスレッドが存在します。 () 方法。 CyclicBarrier のコンテキストでは、すべてのスレッドは互いに待機しているスレッドであり、同じタイプです。

  • CountDownLatch はダウン カウントであり、デクリメントの完了後にリセットすることはできません。CyclicBarrier はアップ カウントで、インクリメントの完了後に自動的にリセットされます。

CountDownLatch の例

スレッドのグループを 2 つ作成します。一方のグループは、もう一方のグループの実行が完了するのを待ってから続行します。

CountDownLatch countDownLatch = new CountDownLatch(5);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
    executorService.execute(() -> {
        countDownLatch.countDown();
        System.out.println("run..");
    });
}
for (int i = 0; i < 3; i++) {  //我们要等上面执行完成才继续
    executorService.execute(() -> {
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("await..");
    });
}
executorService.shutdown();

Print:

run..
run..
run ..
run..
run..
await..
await..
await..

累積スレッドの実行が終了するのを待ってから、メインスレッドが累積結果を出力します

public class ThreadUnsafeExample {
    private int cnt = 0;
    public void add() {
        cnt++;
    }
    public int get() {
        return cnt;
    }
    public static void main(String[] args) throws InterruptedException {
        final int threadSize = 1000;
        ThreadUnsafeExample example = new ThreadUnsafeExample();
        final CountDownLatch countDownLatch = new CountDownLatch(threadSize);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < threadSize; i++) {
            executorService.execute(() -> {
                example.add();
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executorService.shutdown();
        System.out.println(example.get());
    }
}

Print:

997

3同時実行性のシミュレーション

ExecutorService executorService = Executors.newCachedThreadPool();
        CountDownLatch countDownLatch = new CountDownLatch(1);
        for (int i = 0; i < 5; i++) {
            executorService.submit( () -> {
                try {
                    countDownLatch.await();
                    System.out.println("【" + Thread.currentThread().getName() + "】开始执行……");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        Thread.sleep(2000);
        countDownLatch.countDown();//开始并发
        executorService.shutdown();

Print:

【pool-2-thread-2】実行開始...
【pool-2-thread-5】実行開始.. . ;…
【pool-2-thread-1】実行開始……
【pool-2-thread-4】実行開始...

すべてのスレッドが相互に待機します特定のステップが完了するまで続行する前に
        final int totalThread = 3;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < totalThread; i++) {
            executorService.execute(() -> {
                System.out.println("before..");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("after..");
            });
        }
        executorService.shutdown();

印刷:

before..

before..

before ..
after..

後..
後..

以上がJava CountDownLatch カウンターと CyclicBarrier サイクル バリアを定義する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。