Suppose you have 5 threads out of which 1 is a main thread and other 4 are threads that perform some task.

Now you want the main thread to proceed further only after all the 4 worker threads have finished execution.

Example,

When a laptop is started, many tasks are performed such as initialization of network service, graphic interface, input output drivers, pre-configured startup services etc.

When all these have signaled successful startup, then the login screen is displayed. Consider each of these services as a separate thread and login screen display thread as a thread waiting for these threads to complete.

This thread should proceed only when all the service threads have completed their initialization.



wait

notifyAll

CountdownLatch

Read this to know more about java threads.

With traditional java thread implementation, you can do this usingandmethods. But java also provides a simpler method to accomplish this by using a

What is CountDownLatch

CountDownLatch is used to make a thread wait till other threads finish their execution.

When all the threads finish and signal their completion, then the thread which is waiting resumes its execution. CountDownLatch was added in java 1.5.

How to use CountDownLatch in java

A CountDownLatch in java is implemented through a java.util.concurrent.CountDownLatch class. When an object of this class is created, we supply the number of threads for which a thread will wait to finish execution.

This is known as the count of CountDownLatch and it is the value of this count that decides the resumption of waiting thread.

A thread waiting for the execution will resume only when the count becomes 0.

Usage of CountDownLatch is based on below two methods:

await: When this method is called on an object of CountDownLatch , the current thread pauses execution and goes into waiting state.

The thread keeps on waiting till the count of CountDownLatch becomes zero.

This method should be called inside the thread which needs to wait for the other threads to complete.

countDown: This method should be called from inside the worker threads. Each time this method is called, the value of count of CountDownLatch reduces by 1.



CountDownLatch

A CountDownLatch is initialized with a count which is the number of child threads for which the main thread will wait before executing further.

It is an integer. Thread which starts other threads and which wants to wait for these threads to finish calls await . Every child thread when finishes execution, calls countDown method.

This reduces the count by 1. When all the child threads have completed(and have called countDown ), the value of count becomes 0 and main thread resumes its execution.

count of CountDownLatch can also be considered as the number of times for which countDown method should be invoked on the latch so that the waiting thread can resume.

Thus, the concept ofcan be summarized in below steps.

Remember that both await and countDown should be called on the same object of CountDownLatch . Thus, you need to share the object of CountDownLatch among parent and child threads.

CountDownLatch example

Below is a simple example of a CountDownLatch . It consists of a class Task that implements java.lang.Runnable and represents a task that thread needs to perform.

Task of a thread is written inside the overridden run method of java.lang.Runnable interface.

Learn about overriding methods in java here.

This class also accepts an object of java.util.concurrent.CountDownLatch and calls its countDown method once it finishes.

Task.java

class Task implements Runnable { CountDownLatch latch ; /** * Constructor * @param l */ public Task ( CountDownLatch l ) { this . latch = l ; } @Override public void run ( ) { try { System . out . println ( "Started: " + Thread . currentThread ( ) . getName ( ) ) ; Thread . sleep ( 2000 ) ; } catch ( InterruptedException e ) { e. printStackTrace ( ) ; } System . out . println ( "Finished: " + Thread . currentThread ( ) . getName ( ) ) ; // reduce count of latch latch. countDown ( ) ; } } class Task implements Runnable { CountDownLatch latch; /** * Constructor * @param l */ public Task(CountDownLatch l) { this.latch = l; } @Override public void run() { try { System.out.println("Started: " + Thread.currentThread().getName()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Finished: " + Thread.currentThread().getName()); // reduce count of latch latch.countDown(); } }

Below is a main class that creates an object of java.util.concurrent.CountDownLatch with a count of 3. It then creates an object of Task class and supplies the same object to three threads that it creates.



CountDownLatch

countDown

CountDownLatch

await

countDown

countDown

After starting all the three threads, it waits for their execution to complete by calling await on the object ofThis thread will resume execution when all the threads will callmethod on the latch.Note that the object of theon which it callsis also shared with all the three threads for which it is waiting.Each time a thread callsmethod,reduces by 1.Thus, when all the threads call, thereaches 0 and the main thread then continues execution.

MainThread.java

public class MainThread { public static void main ( String [ ] args ) throws InterruptedException { // create an object of countdownlatch with a count of 3 CountDownLatch latch = new CountDownLatch ( 3 ) ; // create a task Task obj = new Task ( latch ) ; // create three worker threads Thread t1 = new Thread ( obj ) ; Thread t2 = new Thread ( obj ) ; Thread t3 = new Thread ( obj ) ; // start threads t1. start ( ) ; t2. start ( ) ; t3. start ( ) ; // current thread will wait for the worker threads to complete latch. await ( ) ; System . out . println ( "All Threads completed!!!" ) ; } } public class MainThread { public static void main(String[] args) throws InterruptedException { // create an object of countdownlatch with a count of 3 CountDownLatch latch = new CountDownLatch(3); // create a task Task obj = new Task(latch); // create three worker threads Thread t1 = new Thread(obj); Thread t2 = new Thread(obj); Thread t3 = new Thread(obj); // start threads t1.start(); t2.start(); t3.start(); // current thread will wait for the worker threads to complete latch.await(); System.out.println("All Threads completed!!!"); } }

Following is the output

Started: Thread-1

Started: Thread-0

Started: Thread-2

Finished: Thread-1

Finished: Thread-2

Finished: Thread-0

All Threads completed!!!

With CountDownLatch in place, the last line will always be printed when all the three threads have finished. Remove the statement latch.await and notice the difference.



Let’s tweak in

count is set when a CountDownLatch is created. Once initialized, count cannot be reset. The thread in which await is called will keep on waiting infinitely till the count becomes zero. If the count is greater than the number of threads, then main thread will be stuck forever. In case you are not sure if a child thread will call countDown using the overloaded await method which takes a timeout value so that the main thread will resume after the specified time and your application will not be stuck forever. For getting the current count value, call getCount method on the object of CountDownLatch . Nothing will happen if countDown method is called and the count is 0.

If you liked this article, then make sure to click the clap icon below to show your appreciation.

0