Java CountDownLatch Example
How to use CountDownLatch in Java?
Theory is easy to read but you cannot understand it until you see it live in action, this is even more true with concurrency and multi-threading. So let's see how to use CountDownLatch in Java with a simple demo. In this example, we have a main thread which is required to wait until all worker thread finished their task. In order to achieve this, I have created a CountDownLatch with number of count equal to 4, which is the total number of worker threads. I then passed this CountDownLatch to each worker thread, whenever they complete their task, they call countDown() method, once last worker thread calls thecountDown() method then the latch is broken and main thread which has been waiting on latch start running again and finished its execution.In order to truly understand this problem, you first need to run by by commenting latch.await() call in main method, without this call main thread will not for any worker thread to finish their execution and it will terminate as soon as possible, may be even before any worker thread get started. If you run again by un-commenting latch.await() then you will always see that main thread has finished last. Why? because await() is a blocking call and it blocks until count reaches zero.
Also, you cannot reuse the latch once count=0, calling await() method on latch will have no effect i.e. thread will not block, but they not throw any exception as well, which is little bit of counter intuitive if you are expecting an IllegalThreadStateException.
Here is the complete program and code to use CountDownLatch in Java :
import java.util.concurrent.CountDownLatch; /** * Java Program to demonstrate how to use CountDownLatch, Its used when a thread * needs to wait for other threads before starting its work. * * @author Javin Paul */ public class CountDownLatchDemo { public static void main(String args[]) throws InterruptedException { CountDownLatch latch = new CountDownLatch(4); Worker first = new Worker(1000, latch, "WORKER-1"); Worker second = new Worker(2000, latch, "WORKER-2"); Worker third = new Worker(3000, latch, "WORKER-3"); Worker fourth = new Worker(4000, latch, "WORKER-4"); first.start(); second.start(); third.start(); fourth.start(); // Main thread will wait until all thread finished latch.await(); System.out.println(Thread.currentThread().getName() + " has finished"); } } class Worker extends Thread { private int delay; private CountDownLatch latch; public Worker(int delay, CountDownLatch latch, String name) { super(name); this.delay = delay; this.latch = latch; } @Override public void run() { try { Thread.sleep(delay); latch.countDown(); System.out.println(Thread.currentThread().getName() + " has finished"); } catch (InterruptedException e) { e.printStackTrace(); } } } Output WORKER-1 has finished WORKER-2 has finished WORKER-3 has finished WORKER-4 has finished main has finished
If you call latch.await() again, after count reaches to zero, it will not stop the main thread again, neither it will throw any Exception, it will just pass through it, as shown below :
// Main thread will wait until all thread finished latch.await(); System.out.println(Thread.currentThread().getName() + " has started running again"); latch.await(); System.out.println(Thread.currentThread().getName() + " has finished"); Output main has started running again main has finished
This is where CountDownLatch is different than CyclicBarrier because you can reuse the barrier to stop the thread even after barrier is broken.
Important points about CountDownLatch in Java
Let's revisit some important things about CountDownLatch in Java. This will help you to retain the knowledge you have just learned :1) When you create an object of CountDownLatch you pass an int to its constructor (the count), this is actually number of invited parties (threads) for an event.
2) The thread, which is dependent on other threads to start processing, waits on latch until every other thread has called count down. All threads, which are waiting on await() proceed together once count down reaches to zero.
3) countDown() method decrements the count and await() method blocks until count == 0
4) Once count reaches to zero, countdown latch cannot be used again, calling await() method on that latch will not stop any thread, but it will neither throw any exception.
5) One of the popular use of CountDownLatch is in testing concurrent code, by using this latch you can guarantee that multiple threads are firing request simultaneously or executing code at almost same time.
6) There is a similar concurrency utility called CyclicBarrier, which can also use to simulate this scenario but difference between CountDownLatch and CyclicBarrier is that you can reuse the cyclic barrier once the barrier is broken but you cannot reuse the CountDownLatch one count reaches to zero.
7) Java 7 also introduced a flexible alternative of CountDownLatch, known as Phaser. It also has number of unarrived party just like barrier and latch but that number is flexible. So its more like you will not block if one of the guest bunks the party.
That's all in this Java CountDownLatch example. In this tutorial, you have learned how to useCountDownLatch in Java to make sure your key thread starts processing once all pre-conditions are full-filled or when all threads are ready. There are two other similar utility, one is called Phaser and other is called CyclicBarrier, if you want a dynamic count, go for Phaser and if you want to reuse the barrier again and again, go for CyclicBarrier. We will see examples of this two synchronizers in Java in our next Java Concurrency tutorial.