Wait for N things with CountDownLatch

Read the explanation
What if

main waits until three loaders have each counted down once. Then the latch opens.

0123456main: start loadersready.await()main: start servingload(db)load(cache)load(config)

Tap any block to see what that thread is doing.

  • Running
  • Waiting / parked
  • Waiting on I/O
Step 1/5

The latch starts at 3: one count for each thing to load.

1CountDownLatch ready = new CountDownLatch(3);2for (String name : List.of("db", "cache", "config")) {3    new Thread(() -> {4        load(name);5        ready.countDown(); // one fewer to wait for6    }, name).start();7}8ready.await(); // main waits until the count reaches 09System.out.println("all loaded, start serving");

Explanation

What just happened

The latch started at 3. main called await() and parked. Each loader called countDown() when it finished: 3, 2, 1, 0. At 0 the latch opened and main went on to “start serving”.

Try the what-if switch

a loader throws: config’s load() throws before it reaches countDown(). The count sticks at 1, and main waits forever. The stack trace goes to config’s thread, so main never hears about it.

When to use it

When one thread must wait for a fixed number of things to happen:

The things counting down don’t have to be threads. Any code can call countDown().

Watch out

try { load(name); } finally { ready.countDown(); }

Common questions

How does CountDownLatch work?

It starts at a count N. await() blocks until the count reaches 0, and each countDown() lowers it by one. Any code can count down, not only threads.

Why does await() hang forever?

A worker probably threw before reaching countDown(), so the count never hit 0. Count down in a finally block, or use await(timeout, unit).

Can a CountDownLatch be reset?

No. It's single-use: once it reaches 0 it stays open. For a reusable meeting point, use CyclicBarrier or Phaser.

Verified: this timeline matches a real program, checked in CI on JDK 21 and 25. How we verify. Unclear or wrong? Tell us