Thread coordination with CountDownLatch and CyclicBarrier
Java 5 introduced many new concurrency primitives and collections, and this post is going to look at two classes that can be used to coordinate threads: CountDownLatch and CyclicBarrier.
A CountDownLatch is initialized with a counter. Threads can then either count down on the latch or wait for it to reach 0. When the latch reaches 0, all waiting threads are released.
A common idiom is to use a latch to trigger a coordinated start or end between threads:
package puredanger.coord;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownDemo {
public static void main(String[] args) throws Exception {
int threads = 3;
final CountDownLatch startLatch = new CountDownLatch(threads);
final CountDownLatch endLatch = new CountDownLatch(threads);
ExecutorService svc = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
svc.execute(new Runnable() {
public void run() {
try {
log(“At run()”);
startLatch.countDown();
startLatch.await();
log(“Do work”);
Thread.sleep((int) (Math.random() * 1000));
log(“Wait for end”);
endLatch.countDown();
endLatch.await();
log(“Done”);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Thread.sleep(100);
}
}
private static void log(String msg) {
System.out.println(System.currentTimeMillis() + “: ”
+ Thread.currentThread().getId() + ” ” + msg);
}
}
In this code, you’ll see two latches get initialized. Each thread that starts up counts down on the latch and awaits the latch counting down to 0 (when all threads have been initialized). Similarly, each thread waits for all threads to complete at the same time.
Running this program yields:
1194812267416: 7 At run()
1194812267517: 8 At run()
1194812267618: 9 At run()
1194812267618: 9 Do work
1194812267618: 7 Do work
1194812267619: 8 Do work
1194812267673: 7 Wait for end
1194812267688: 8 Wait for end
1194812268023: 9 Wait for end
1194812268023: 9 Done
1194812268023: 7 Done
1194812268023: 8 Done
You can see that each thread hits run() at different times, but proceeds past the barrier at the same time. They each then do some random amount of work and wait for the latch, then proceed past it together.
In the example above, each thread waits forever for the latch to trigger. You can also choose to wait for a specified time period before giving up. And you can check the latch to see how many threads have arrived and are now waiting. Each CountDownLatch instance can only be used once and is then dead.
If you want a set of threads to repeatedly meet at a common point, you are better served by using a CyclicBarrier. A common use for this is in multi-threaded testing where it is typical to start a bunch of threads, meet, do some stuff, meet, validate some assertions, repeatedly.
The prior program can be simplified by replacing the two latches with a single barrier:
package puredanger.coord;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierDemo {
public static void main(String[] args) throws Exception {
int threads = 3;
final CyclicBarrier barrier = new CyclicBarrier(threads);
ExecutorService svc = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
svc.execute(new Runnable() {
public void run() {
try {
log(“At run()”);
barrier.await();
log(“Do work”);
Thread.sleep((int) (Math.random() * 1000));
log(“Wait for end”);
barrier.await();
log(“Done”);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Thread.sleep(100);
}
}
private static void log(String msg) {
System.out.println(System.currentTimeMillis() + “: ”
+ Thread.currentThread().getId() + ” ” + msg);
}
}
We can see here that the threads can repeatedly wait at the barrier, which implicitly counts down until all threads have arrived, then releases all threads.
Another nice trick with CyclicBarrier is that a Runnable action can be associated with the barrier to be run by the last thread reaching the barrier. You can very simply build a start/end timer for testing with this functionality:
package puredanger.coord;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TimerBarrierDemo {
public static void main(String[] args) throws Exception {
int threads = 3;
final CyclicBarrier barrier = new CyclicBarrier(threads, new BarrierTimer());
ExecutorService svc = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
svc.execute(new Runnable() {
public void run() {
try {
barrier.await();
long sleepTime = (int) (Math.random() * 1000);
System.out.println(Thread.currentThread().getId() + ” working for ” + sleepTime);
Thread.sleep(sleepTime);
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
private static class BarrierTimer implements Runnable {
private long start;
public void run() {
if (start == 0) {
start = System.currentTimeMillis();
} else {
long end = System.currentTimeMillis();
long elapsed = (end – start);
System.out.println(“Completed in ” + elapsed + ” ms”);
}
}
}
}
Here we rely on knowing that the barrier will be reached exactly twice – once at start and once at end. The first time it’s reached, we record a timestamp and the second time it’s reached we print out the timing. When we construct our barrier, we give it an instance of this timer class. Each thread then waits to start on the barrier, works for a random amount of time, and waits for the end barrier.
A run looks like this:
9 working for 35
7 working for 341
8 working for 371
Completed in 372 ms
Generally, you should expect the recorded elapsed time to be the maximum of the working time of any of the threads.
CyclicBarrier has a few additional tricks as well – threads can wait for a time period instead of forever, check whether a barrier has been broken (by interruption or forcibly with a reset() method), and determine the number of parties and the number currently waiting.
This is the first of a series of occasional posts on the concurrency classes added in Java 5 on. Next in the series will be a little program I call “The Hungry Philosophers”.

Hi! My name is Alex Miller and I live in St. Louis. I write code for a living and currently work for
<hint> I bet those hungry philosophers are starving by now! </hint>
nice article.
However i’d like to point out that the best use of cyclicbarrier is when a few threads want to wait for each other to reach a certain point. Bear in mind that the parent thread does not stop for the child threads unless u barrier.await(); on threads+1.
If u want that the parent thread should wait for the children then countdownlatch is the way to go. You can create a latch with the number_of_threads and then each thread can just countDown(); and the parent can await() on the same latch.
Isn’t it a little dangerous to mix the barrier with the executor in this way? If you were to change the execution policy so that for example fewer threads were used then the threads won’t get released.
So it looks like the tasks and the execution policy are coupled tightly to the thread count.
I don’t know if I’d say it was dangerous. You’re correct that the thread count and barrier participants must be linked but as long as that invariant is maintained I think it’s fine.
This is kind of a common problem with barriers in that the participant count must be a) known in advance and b) fixed. The new Phaser class being added in JDK 7 is more flexible in this regard as the participant count can change during the life of the phaser.
Let me qualify that a little: in a real world project the thread allocation policy and the task logic might not nicely be co-located in the same file. Then a developer might come along and swap the fixed thread executor to one with fewer threads as we are encouraged to do with the executor framework, without realizing the impact until the application freezes.
I take your point that with discipline this wouldn’t happen, just checking my understanding of cyclic barriers really.
Great concurrency refcard b.t.w.