たCountDownLatchのJavaツールの同時実行性とCyclicBarrierを

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/ThinkWon/article/details/102556958

カウントダウンたCountDownLatch

マルチスレッドは、時には他のタスクを完了するために、複数のスレッドを待つ必要がある、メインスレッドがこのビジネスシナリオにビジネス機能をダウン継続することができ、ビジネス機能に協力した後、あなたは通常、主を聞かせて、Threadクラスはメソッドを結合を使用することができます実装をダウン継続するメインスレッドを実行しているスレッドに参加されるのを待っているスレッドの後。もちろん、スレッド間のメッセージング機構の使用も行うことができます。私たちが完了するのに非常に便利なように実際には、Javaの並行処理ユーティリティクラスは、同様の「カウントダウン」そのようなツールを提供し、このビジネスシナリオは語りました。

、たCountDownLatchを理解する非常に人気の例を与えることができるようにするには、選手、レースを実行しているゲームに関わる6人の選手があり、審判が最後に6人の選手としての時間を分割することを想定し、それはプレイヤーが最後に到達するたびに考えられる時間があるときに、審判のためには、時限タスクの小さいです。すべての選手がフィニッシュラインに到達するまでは、審判のタスクが完了します。時間カウンタが0になるまでスレッドがCountDownLatch.countDown方法は、カウンタの値になります呼び出すとき6人の選手が、6つのスレッドに同化することができるダウン継続する審判(呼び出されたスレッドを待って)、1だけデクリメントされます実行。

のは、重要なメソッドたCountDownLatchをいくつか見てみましょう。

工法のたCountDownLatchスタートが見えます:

public CountDownLatch(int count)

コンストラクタを呼び出した後、整数N、たCountDownLatchを通過するcountDown時間がゼロに達するまでNを減少させる方法を、Nは、現在と呼ばれるawait継続するスレッドの方法。

たCountDownLatchのアプローチは多くないが、一つずつそれらを列挙:

  1. 待つ()は例外:InterruptedExceptionをスロー:受信Nのコンストラクタメソッドまで、呼び出し側スレッドがダウンし続けるために、ゼロ時間に達します。
  2. (長いタイムアウト、TimeUnitで単位)待つ:上記の特徴と一致するが、ここでは制限時間を有する、方法を待って、指定されたタイムアウト時間の後にメソッドの呼び出し側スレッドに関係なくNがゼロに減少したかどうか、ダウン継続し、待機します;
  3. カウントダウン():たCountDownLatchは、初期値Nを1だけデクリメントさせます。
  4. 長い同様にgetCount():現在のたCountDownLatchのメンテナンスの値を取得します。

たCountDownLatchの具体的な使用方法を説明するための具体的な例で下:

public class CountDownLatchDemo {

    private static CountDownLatch startSignal = new CountDownLatch(1);
    //用来表示裁判员需要维护的是6个运动员
    private static CountDownLatch endSignal = new CountDownLatch(6);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        System.out.println("各位运动员准备啦!!!");
        for (int i = 0; i < 6; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 运动员等待裁判员响哨!!!");
                    // 确保所有运动员准备完毕
                    Thread.sleep(1000);
                    startSignal.await();

                    System.out.println(Thread.currentThread().getName() + " 正在全力冲刺");
                    endSignal.countDown();
                    System.out.println(Thread.currentThread().getName() + " 到达终点");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        //将executorService转换为ThreadPoolExecutor,ThreadPoolExecutor有方法 getActiveCount()可以得到当前活动线程数
        int threadCount = ((ThreadPoolExecutor)executorService).getActiveCount();
        if (threadCount == 6) {
            System.out.println("裁判员响哨...");
            startSignal.countDown();

            endSignal.await();
            System.out.println("所有运动员到达终点,比赛结束!");
        }


        executorService.shutdown();
    }

}

出力

各位运动员准备啦!!!
pool-1-thread-1 运动员等待裁判员响哨!!!
pool-1-thread-3 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员等待裁判员响哨!!!
pool-1-thread-5 运动员等待裁判员响哨!!!
pool-1-thread-4 运动员等待裁判员响哨!!!
pool-1-thread-6 运动员等待裁判员响哨!!!
裁判员响哨...
pool-1-thread-5 正在全力冲刺
pool-1-thread-5 到达终点
pool-1-thread-6 正在全力冲刺
pool-1-thread-2 正在全力冲刺
pool-1-thread-2 到达终点
pool-1-thread-1 正在全力冲刺
pool-1-thread-1 到达终点
pool-1-thread-3 正在全力冲刺
pool-1-thread-3 到达终点
pool-1-thread-4 正在全力冲刺
pool-1-thread-6 到达终点
pool-1-thread-4 到达终点
所有运动员到达终点,比赛结束!

例コードたCountDownLatch二組、第endSignalNの値が0になるまでたCountDownLatchを保つように、メインスレッド(審判)が他のスレッドまで(プレーヤー)を待たなければならないように制御します。もう一つのstartSignal他のスレッドに「注文」を作るためにメインスレッドのためには、startSignalは1のたCountDownLatch初期値を引用して、最初のパスます実行方法の他のスレッドを実行するstartSignal.await()ようにブロックされて呼び出すことで、メインスレッドまでこれらのスレッドstartSignal.countDown();は、値Nマイナス実行の各スレッドのたCountDownLatchメンテナンス後1、値N 0、ダウン実行する他のスレッドと、RUNメソッドが通過するendSignal.countDown();ためにendSignal、提出6つのタスクにスレッドプールので、減少数値を維持しますそれはとても、マイナス6倍となるendSignal値は、最終的にゼロで、そうではメインスレッドになります維持latch.await();の実装を下に継続して、ブロックされて終わり。

また、あなたがカウントダウンされたCountDownLatchメソッドを呼び出すと、現在のスレッドがブロックされていない、それは、このような本例では継続されます出力として、ダウン続けることに注意してくださいpool-1-thread-4 到达终点

サイクリングフェンスCyclicBarrierを

CyclicBarrierをもマルチスレッドユーティリティの同時実行制御され、カウント待ったCountDownLatch同じ機能を持っていますが、より強力たCountDownLatchに比べて。

CyclicBarrierを、ここに引用した一般的な例を理解するために。キャンペーンを実行するときにゲームオープン、我々は、選手の次のパレードは、あなたがゲームの開始時に、6滑走路があるとしたとき、あなたはレース開始点の開始時に6人の選手が立ち上がっ必要がある場合をシミュレート審判の後に実行を開始するために笛を吹きます。滑走路の出発点は、それ以外の場合は臨界点で、「バリア」に相当し、6人の選手が類推にスレッドということ、それから、先に進む前に、波一緒に玉石を意味し、指定されたポイントに到達しなければならない。この6つのスレッドです各スレッドは、あなたが一緒にチーYiboをこすりできるようになるまで待ってブロックされていました。巡回循環が複数のスレッドが波の後に一緒に考え出すのためにCyclicBarrierをが、まだ有効であることを意味する、私たちは次の波を一緒に考え出すし続けることができます。次のように行わCyclicBarrierを回路図:

ここに画像を挿入説明

複数のスレッドが指定された点に達した場合は、継続してダウンして続行します。言葉がダウンして実行するために一緒に考え出すのためだけに6本の波のであれば、それは少し報告し、6人の選手の同等の6つのスレッドを想定数の感覚のようなものだ、トラックの出発点に統計の時に数を報告します。CyclicBarrierを次がまだ有効である、一度使用した後、あなたがたCountDownLatch差の一つであるカウンタとして使用し続けることができますここでCyclicBarrierを受信コンストラクタによって6つのスレッド、カウンタ6の即ち初期値、。

CyclicBarrierをの主な方法は、以下を見てください:

//等到所有的线程都到达指定的临界点
await() throws InterruptedException, BrokenBarrierException 

//与上面的await方法功能基本一致,只不过这里有超时限制,阻塞等待直至到达超时时间为止
await(long timeout, TimeUnit unit) throws InterruptedException, 
BrokenBarrierException, TimeoutException 

//获取当前有多少个线程阻塞等待在临界点上
int getNumberWaiting()

//用于查询阻塞等待的线程是否被中断
boolean isBroken()

//将屏障重置为初始状态。如果当前有线程正在临界点等待的话,将抛出BrokenBarrierException。
void reset()

また、CyclicBarrierを、このようなコンストラクタを提供する、ということに注意してください。

public CyclicBarrier(int parties, Runnable barrierAction)

スレッドを指定すると、指定された臨界点に達したときには、操作が次を行うことができるbarrierActionによって渡すことができ、使用することができます。

選手によってモデル化された、上記の例では、私たちに簡単な例の下には、我々はCyclicBarrierをの使い方を見てください。

public class CyclicBarrierDemo {

    //指定必须有6个运动员到达才行
    private static CyclicBarrier barrier = new CyclicBarrier(6, () ->
            System.out.println("所有运动员入场,裁判员一声令下!!!!!")
    );

    public static void main(String[] args) {
        System.out.println("运动员准备进场,全场欢呼............");

        ExecutorService service = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 6; i++) {
            service.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 运动员,进场");
                    barrier.await();
                    System.out.println(Thread.currentThread().getName() + "  运动员出发");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }
    }

}

出力

运动员准备进场,全场欢呼............
pool-1-thread-1 运动员,进场
pool-1-thread-4 运动员,进场
pool-1-thread-3 运动员,进场
pool-1-thread-2 运动员,进场
pool-1-thread-6 运动员,进场
pool-1-thread-5 运动员,进场
所有运动员入场,裁判员一声令下!!!!!
pool-1-thread-5  运动员出发
pool-1-thread-1  运动员出发
pool-1-thread-6  运动员出发
pool-1-thread-3  运动员出发
pool-1-thread-2  运动员出发
pool-1-thread-4  运动员出发

6人の選手(スレッド)、それ以外の場合は、呼び出しを待ってブロックされます、ダウン継続する(バリア)時間を指定された臨界点に達したとき、出力からわかるようawait()

CyclicBarrierを持つたCountDownLatch比較

たCountDownLatchツールはCyclicBarrierを持つ同時制御するために使用され、カウンタとして理解することができるが維持されるが、二人はまだ異なる強調を持っています。

  1. 一般的に、その後のスレッドのこのグループは、再び同時に実行される特定の状態に相互に待機しているスレッドのグループに使用CyclicBarrierを;たCountDownLatch A一般タスクを実行するいくつかの他のスレッドを待機するスレッドのために使用される、それが実行された後たCountDownLatchは、スレッドを強調そして他の多くのスレッドが何かを完了します。CyclicBarrierを複数のスレッド逆数であるので、我々は完了し、その後、手をつないで行きます。
  2. カウントダウンたCountDownLatchのメソッドを呼び出した後、現在のスレッドをブロックしない、それがダウンしていきます。そしてCyclicBarrierをメソッドを待って呼び出し、指定されたスレッドCyclicBarrierをするまで、現在のスレッドをブロックするすべてダウンし続けるために、時間の指定点に到達しました実行;
  3. このような複数のスレッドの現在の状態を取得する方法)getNumberWaiting()、isBroken(スルーとして、よりCyclicBarrierをする方法を提供しながらたCountDownLatch少ない方法は、操作が比較的簡単で且つCyclicBarrierをコンストラクタbarrierActionを渡すことができ、すべての指定しますビジネス機能に到達したときにスレッドが実行されます。
  4. たCountDownLatchは再利用可能ではない、とCyclicLatchを多重化することができます。

おすすめ

転載: blog.csdn.net/ThinkWon/article/details/102556958