How to use CountDownLatch

Sometimes we need to synchronize the results of several threads running simultaneously, we need to run some task once some others have finished. We can use CountDownLatch class to do this.

The Pizza Example

Let’s use another silly example. I want to have pizza for dinner, so I’m going to cook it. While the oven is preheating (it takes 5 min) I can prepare the pizza itself (it takes 2 min). Once everything is ready I can put the pizza inside the oven. That’s easy: as the oven takes longer to get preheated than me to get the pizza ready, I can put the pizza inside as soon as the oven is ready. There’s no need to synchronize threads…

But sometimes I turn on the radio and the music distracts me. In this case it takes me to prepare the pizza from 4 to 7 minutes. We don’t know which process will finish first, we have to wait until both processes have finished to put the pizza in the oven.

final CountDownLatch latch = new CountDownLatch(2);

Thread preheat = new Thread() {

	@Override
	public void run() {
		// The oven takes 5 minutes to get ready
		// (we use 5 seconds instead)
		try {
			Thread.sleep(5000);
			System.out.println("The oven is ready.");
		} catch (InterruptedException e) {
		} finally {
			latch.countDown();
		}
	}
	
};

Thread preparePizza = new Thread() {

	@Override
	public void run() {
		// It takes me from 4 to 7 minutes to prepare the pizza
		Random random = new Random();
		int time = random.nextInt(3000);
		try {
			Thread.sleep(4000+time);
			System.out.println("The pizza is ready.");
		} catch (InterruptedException e) {
		} finally {
			latch.countDown();
		}
	}
	
};

preheat.start();
preparePizza.start();

try {
	latch.await();
	System.out.println("The pizza is in the oven.");
} catch (InterruptedException e) {
}

First of all we’re starting a CountDownLatch instance. We pass the number 2 as an argument to the constructor to tell it that there will be two processes to wait for.

Next we create a thread for the oven, the sleep simulates the preheating process. We’re using seconds instead of minutes so the program won’t be idle for such a long time.

Next we create the preparing pizza thread. With a random number we simulate the distracting song from the radio. At the end of both processes there is a line, latch.countDown(), that tells the CountDownLatch that the process has finished. You may have noticed that latch.countDown() is in the finally block. We want it to be executed no matter what exception is thrown. If the program never reaches this line it’ll hang!

Next we start both threads and tell the latch to wait for them. This is accomplished with the latch.await() line. It’ll suspend the main thread until both processes have finished (when latch.countDown() is reached).

After running this program we get something like this:

The oven is ready.
The pizza is ready.
The pizza is in the oven.

But we could also get:

The pizza is ready.
The oven is ready.
The pizza is in the oven.

Regardless of how long it takes me to prepare the pizza, “The pizza is in the oven.” won’t be shown until both tasks have finished.

Leave a Reply

Your email address will not be published. Required fields are marked *