CountDownLatch
This is used to synchronize one or more tasks by forcing them to wait for the completion of a set of operations being performed by other tasks.
You give an initial count to a CountDownLatch object, and any task that calls await( ) on that object will block until the count reaches zero. Other tasks may call countDown( ) on the object to reduce the count, presumably when a task finishes its job. A CountDownLatch is designed to be used in a one-shot fashion; the count cannot be reset. If you need a version that resets the count, you can use a CyclicBarrier instead.
The tasks that call countDown( ) are not blocked when they make that call. Only the call to await( ) is blocked until the count reaches zero.
A typical use is to divide a problem into n independently solvable tasks and create a CountDownLatch with a value of n. When each task is finished it calls countDown( ) on the latch. Tasks waiting for the problem to be solved call await( ) on the latch to hold themselves back until it is completed. Here's a skeleton example that demonstrates this technique:
//: concurrency/CountDownLatchDemo.java import java.util.concurrent.*; import java.util.*;
import static net.mindview.util.Print.*;
// Performs some portion of a task: class TaskPortion implements Runnable { private static int counter = 0; private final int id = counter++; private static Random rand = new Random(47); private final CountDownLatch latch; TaskPortion(CountDownLatch latch) { this.latch = latch;
latch.countDown(); } catch(InterruptedException ex) { // Acceptable way to exit
public void doWork() throws InterruptedException { TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
print(this + "completed");
public String toString() {
// Waits on the CountDownLatch: class WaitingTask implements Runnable { private static int counter = 0; private final int id = counter++; private final CountDownLatch latch; WaitingTask(CountDownLatch latch) { this.latch = latch;
latch.await();
print("Latch barrier passed for " + this); } catch(InterruptedException ex) { print(this + " interrupted");
public String toString() {
return String.format("WaitingTask %1$-3d ", id);
public class CountDownLatchDemo { static final int SIZE = 100;
public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); // All must share a single CountDownLatch object: CountDownLatch latch = new CountDownLatch(SIZE); for(int i = 0; i < 10; i++)
- execute(new WaitingTask(latch)); for(int i = 0; i < SIZE; i++)
- execute(new TaskPortion(latch)); print("Launched all tasks");
- shutdown(); // Quit when all tasks complete
TaskPortion sleeps for a random period to simulate the completion of part of the task, and WaitingTask indicates a part of the system that must wait until the initial portion of the problem is complete. All tasks work with the same single CountDownLatch, which is defined in main( ).
Exercise 32: (7) Use a CountDownLatch to solve the problem of correlating the results from the Entrances in OrnamentalGarden.java. Remove the unnecessary code from the new version of the example.
Post a comment