JAVAコンカレントマルチスレッドクラス(2):同期バリアCyclicBarrierの理解と使用

前書き

CyclicBarrierは、文字通り、Cyclicバリア(バリア)を意味します。

スレッドのグループがバリア(同期ポイントとも呼ばれます)に達したときにスレッドのグループをブロックする必要があり、最後のスレッドがバリアに達するまでバリアは開きません。

バリアによってインターセプトされたすべてのスレッドは引き続き機能します。CyclicBarrierのデフォルトの構築方法はCyclicBarrier(int partys)であり、そのパラメーターはバリアーによってインターセプトされたスレッドの数を示します。

各スレッドがawaitメソッドを呼び出して、バリアに到達したことをCyclicBarrierに通知すると、現在のスレッドがブロックされます。

コード例は次のとおりです。

public class CyclicBarrierTest {
    static CyclicBarrier c = new CyclicBarrier(2);
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {

                }
                System.out.println(1);
            }
        }).start();

        try {
            c.await();

        } catch (Exception e) {

        }
        System.out.println(2);
    }
}
输出
-> 2
-> 1
或者输出
-> 1
-> 2
如果把new CyclicBarrier(2)修改成new CyclicBarrier(3)则主线程和子线程会永远等待,因为没有第三个线程执行await方法,即没有第三个线程到达屏障,所以之前到达屏障的两个线程都不会继续执行。

CyclicBarrierは、より高度なコンストラクターCyclicBarrier(intパーティ、Runnableバリアアクション)も提供します。これは、スレッドがバリアに到達したときにバリアアクションを最初に実行するために使用され、より複雑なビジネスシナリオを処理するのに便利です。

 

コードは以下のように表示されます:

 

public class CyclicBarrierTest2 {
    static CyclicBarrier c = new CyclicBarrier(2, new A());
    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
                System.out.println(1);
            }
        }).start();
 
        try {
            c.await();
        } catch (Exception e) {
        }
        System.out.println(2);
    }

    static class A implements Runnable {
        @Override
        public void run() {
            System.out.println(3);
        }
    }
}

=== 输出
-> 3
-> 1
-> 2

CyclicBarrierのアプリケーションシナリオ

CyclicBarrierを使用して複数のスレッドでデータを計算し、最後に計算結果のアプリケーションシナリオをマージできます。たとえば、Excelを使用してすべてのユーザーの銀行フローを保存し、各シートは過去1年間の口座の各銀行フローを保存します。次に、ユーザーの毎日の銀行フローをカウントし、まずマルチスレッドを使用して各シートの銀行フローを処理する必要があります。すべての実行が完了すると、各シートの毎日の平均銀行回転率が取得され、最後に、これらのスレッドの計算結果を使用してExcel全体の毎日の平均銀行回転率が計算されます。

 

CyclicBarrierとCountDownLatchの違い 

CountDownLatchカウンターは1回しか使用できません。CyclicBarrierのカウンターは、reset()メソッドを使用してリセットできます。したがって、CyclicBarrierは、より複雑なビジネスシナリオを処理できます。たとえば、計算でエラーが発生した場合、カウンターをリセットして、スレッドを再度実行させることができます。

CyclicBarrierは、CyclicBarrierによってブロックされたスレッドの数を取得するgetNumberWaitingメソッドなど、他の便利なメソッドも提供します。isBrokenメソッドは、ブロックされたスレッドが中断されているかどうかを知るために使用されます。たとえば、次のコードは実行後にtrueを返します

isBrokenの使用コードは次のとおりです。

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest3 {

    static CyclicBarrier c = new CyclicBarrier(2);

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
            }
        });
        thread.start();
        thread.interrupt();
        try {
            c.await();
        } catch (Exception e) {
            System.out.println(c.isBroken());
        }
    }
}


=====> 输出

 true 

 

おすすめ

転載: blog.csdn.net/bj_chengrong/article/details/108704141