公開日:3/14/2022  更新日:3/26/2022

  • twitter
  • facebook
  • line

【Java】サンプルコードでCountDownLatch の挙動を確認してみた

CountDownLatch とは?

ほかのスレッドで実行中の操作セットが完了するまで、1つ以上のスレッドを待機可能にする同期化支援機能です。
主にスレッド間の待ち合わせ処理などで使用されます。

仕様

1.CountDownLatchを待機させたいスレッド数で初期化する
2.countDown()メソッド でカウント数を1減らす
3.await() メソッドでラッチカウントがゼロになるまで現在のスレッドを待機させる
4.ラッチカウントがゼロになった場合、await() メソッドは trueを返却して処理を復帰させる

サンプル例 1

10スレッドを実行する。
18行目 の countDownLatch.await(); でラッチカウントが0になるまで処理待機。
10スレッドの処理が完了するとラッチカウントが0になり処理復帰する。
19行目の finish が出力される。

import java.util.concurrent.CountDownLatch;

public class Main{

    private static final int LOOP_COUNT= 10;
    private static CountDownLatch countDownLatch = new CountDownLatch(LOOP_COUNT);

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < LOOP_COUNT; i++) {
            new Thread(() -> {
                System.out.println("wait");
                countDownLatch.countDown();
            }) .start();
        }
        System.out.println("do someting");
        countDownLatch.await();
        System.out.println("finish");
    }
}

実行結果

wait
wait
wait
wait
do someting
wait
wait
wait
wait
wait
wait
finish

サンプル例 2 (待機時間を指定あり)

10スレッドを実行。
10スレッド目だけ10秒スリープさせる。
27行目 の countDownLatch.await(5L, TimeUnit.SECONDS); でラッチカウントが0になるまで処理待機。
タイムアウトを5秒で設定しているので5秒経過後にcountDownLatch.await(5L, TimeUnit.SECONDS);false が返却される。
30行目でtimeoutが出力される。
32行目の finish が出力される。
10秒後に10スレッド目の処理が終わり wait が出力される。
この時点でラッチカウントは0となるので、countDownLatch.await(5L, TimeUnit.SECONDS);の返り値は true となる。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Main{

    private static final int LOOP_COUNT= 10;
    private static CountDownLatch countDownLatch = new CountDownLatch(LOOP_COUNT);

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < LOOP_COUNT; i++) {
        	int count = i;
            new Thread( () -> {
                //最後のスレッドだけ10秒スリープさせる
                if(count== 9) {
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {}
                }
                System.out.println("wait");
                countDownLatch.countDown();
            }).start();
        }
        System.out.println("do someting");
        //5秒経過するまでスレッドを待機させる
        if (countDownLatch.await(5L, TimeUnit.SECONDS)) {
        	System.out.println("success");
        }else{
        	System.out.println("timeout");
        };
        System.out.println("finish");
    }
}

実行結果

wait
wait
do someting
wait
wait
wait
wait
wait
wait
wait
timeout
finish
wait

参考URL

1) Java - CountDownLatchを使用する方法、および例
2) クラスCountDownLatch

戻る