Java Gold SE11対策:CyclicBarrier / CountDownLatch の使い方と違い

アイキャッチ画像

マルチスレッドで「複数の処理を同時に進めたい。でも途中で一度集まって、足並みを揃えたい」――
そんなときに使えるのが CyclicBarrier や CountDownLatch です。

それぞれ似た目的で使われますが、使い方や挙動が大きく異なります。

本記事では、「スレッドの待ち合わせ」をテーマに、

  • 両者の違い
  • Java Gold SE11 試験での狙われポイント
  • 実際のコード例

を交えて解説します。

何のために使うの?

たとえば、3人の作業者(スレッド)がバラバラに作業しているとして:

作業A → 作業B → 作業C

それぞれのスレッドが「作業A」を終えたら、次のステップに進む前に全員揃うのを待ちたい
→ この「待ち合わせ処理」を実現するのが CyclicBarrier や CountDownLatch です。

CountDownLatch:一定回数カウントダウンするまで待つ

特徴

  • 一方向にカウントするだけ。再利用できない。
  • 「N回 countDown() が呼ばれるまで待機」する仕組み。
  • 複数のスレッドが await() で待機し、あるカウントで一斉に解除。

サンプルコード

import java.util.concurrent.CountDownLatch;

public class LatchExample {

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

        CountDownLatch latch = new CountDownLatch(3); // 🔢 3回のカウントが必要

        Runnable task = () -> {

            System.out.println(Thread.currentThread().getName() + ” 処理開始”);

            try {

                Thread.sleep(1000); // 擬似処理

            } catch (InterruptedException e) {}

            System.out.println(Thread.currentThread().getName() + ” 処理完了”);

            latch.countDown(); // 🔻 カウント減らす

        };

        for (int i = 0; i < 3; i++) {

            new Thread(task).start();

        }

        latch.await(); // 👈 ここでスレッド全員の終了を待つ

        System.out.println(“全員完了。メイン処理へ”);

    }

}

CyclicBarrier:複数スレッドの合流ポイント

特徴

  • 再利用可能(cyclic) なバリア(待ち合わせ)。
  • 指定スレッド数が await() に到達したタイミングで、一斉に次の処理へ進む。
  • 到達時に実行される「バリアアクション(Runnable)」も指定可能。

サンプルコード

import java.util.concurrent.CyclicBarrier;

public class BarrierExample {

    public static void main(String[] args) {

        CyclicBarrier barrier = new CyclicBarrier(3, () -> {

            System.out.println(“🔔 全スレッドが揃いました!”);

        });

        Runnable task = () -> {

            System.out.println(Thread.currentThread().getName() + ” 作業中”);

            try {

                Thread.sleep(1000);

                barrier.await(); // 🧍‍♂️ バリア到達を宣言

                System.out.println(Thread.currentThread().getName() + ” 次の処理へ”);

            } catch (Exception e) {

                e.printStackTrace();

            }

        };

        for (int i = 0; i < 3; i++) {

            new Thread(task).start();

        }

    }

}

違いを比較

特徴CountDownLatchCyclicBarrier
再利用性❌ 1回使い切り✅ 再利用可能
カウント操作countDown()await() で自動カウント
主な使い方スレッドの終了待ちスレッドの合流点
バリアアクション❌ なし✅ 指定可
試験での狙い所await() のブロックawait() 後に一斉進行

Java Gold SE11でのポイント

  • CountDownLatch の await() と countDown() の関係を問われる
    →「N 回 countDown() されるまで await() がブロックされる」
  • CyclicBarrier のスレッド合流/バリアアクションの発火タイミング
    →「最後のスレッドが await() したときにアクション実行」
  • InterruptedException や BrokenBarrierException の例外処理が必要
    →試験では例外スローや try-catch の有無もチェックされる

まとめ

用語ポイント
CountDownLatch1回限りのスレッド待機処理。完了通知として使う
CyclicBarrier複数スレッドの同期ポイント。再利用可能で合流アクションも指定可
await()スレッドが「到達した」ことを示す。解除されるまでブロックされる
countDown()Latch のカウントを1減らす。全カウントで待機スレッドが解除される