Java CountDownLatch Example - Multithreading and Concurrency Tutorial

The CountDownLatch is an important concurrency utility class which was added in JDK 1.5 but unfortunately, many Java developers still struggle to understand and use this powerful tool. You can use CountDownLatch if you are spawning multiple threads to do different jobs and want to know when exactly all tasks are finished so that you can move to next stage. In other words, you can block a thread until other threads complete their task. One of the good examples where you can use CountDownLatch is an application which downloads data from a database or another application. For example, we are creating a Java program to download all Udemy courses. Since Udemy has thousands of courses, you create different threads to download different categories e.g. technology, development etc.

Your application can only be started once all data is loaded and to know the status of your loading progress you can create a CountDownLatch.

Suppose, you have spawned 5 threads to load five different categories of data then you can create a CountDownLatch with 5 counts and then bring down the count by 1 when loading of one category is finished. You can do this by calling the countDown() method.

Since different thread will take different time, your main thread can wait until all threads have completed and it can do by checking the remaining count by calling getCount() method or just calling the CountDownLatch.await() method, which causes current thread to wait until the latch has counted down to zero or the thread is interrupted.

Once the count becomes zero, it can announce that application is started and ready to accept client connections.

Here is a simplified version of Java Code for above scenario which demonstrates downloading data in multiple threads and using CountDownLatch to check completion.



CountDownLatch Example in Java

package tool;

import java.util.concurrent.CountDownLatch;

/**
 * 
 * A simple example of CountDownLatch in Java
 */
public class CountDownLatchDemo {

  private static final CountDownLatch loadingLatch = new CountDownLatch(3);

  public static void main(String args[]) {

    Thread pythonCourseLoader = new Thread("PythonCourseLoader") {

      @Override
      public void run() {
        System.out.println("Loading all Python courses from Udemy..");
        // loading Python courses ....
        // loading completed, time to count down
        System.out.println("loading completed for Python courses");
        loadingLatch.countDown();
      }
    };

    Thread javaCourseLoader = new Thread("JavaCourseLoader") {
      @Override
      public void run() {
        System.out.println("Loading all Java courses from Udemy ..");
        // loading Java courses ....
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println("loading completed for Java courses");
        loadingLatch.countDown();
      }
    };

    Thread developmentCourseLoader = new Thread("developmentCourseLoader") {
      @Override
      public void run() {
        System.out.println("Loading all Develoment courses from Udemy ..");
        // loading development courses ....
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

        System.out.println("loading completed for development courses");
        loadingLatch.countDown();
      }
    };

    pythonCourseLoader.start();
    javaCourseLoader.start();
    developmentCourseLoader.start();

    while (loadingLatch.getCount() != 0) {
      // wait
    }

    // loadingLatch.await();

    System.out.println("all done.");
  }
}

Output:
Loading all Python courses from Udemy..
loading completed for Python courses
Loading all Development courses from Udemy ..
Loading all Java courses from Udemy ..
loading completed for Java courses
loading completed for development courses
all done.


In this program, we have just three threads. One to download all Python courses, second to download all Java courses and the third one to download all Development courses.

I have created a CountDownLatch object with 3 counts as a static final variable:

CountDownLatch loadingLatch = new CountDownLatch(3);

After that, we have three threads, which downloads data, in our case they don't do anything just sleep for 1, 2, and 3 seconds.

Every time a thread completes its execution it calls the countDown() method on the loadingLatch object.

The main() method keep checking for remaining counts using getCount() method and do whatever it wants to do only when the count reaches zero. Though I have used a while loop with getCount(), you can better use latch.await() method for waiting.

A picture is said to be worth a thousand words, so I tried to make this diagram to explain the concept to you. In this diagram you can see that our main thread is waiting on CoutnDownLatch until all thread calls the countdown and count reaches zero, after that, it progressed further.

In short, the main thread was blocked waiting for other loader thread to finish their job.

Btw, If you are not familiar with essential threading concepts e.g. wait, notify, sleep, blocking etc, I suggest you first go through Complete Java Masterclass to learn them.


Java CountDownLatch Example - When and How to Use It




CountDownLatch - Important Points

Now that you know what is CountDownLatch in Java and how to use it for inter-thread communication and synchronization. It's time to revise and remember some important points:

1. The CountDownLatch utility or class is only available on JRE 1.5 or later version.

2. You cannot reuse the latch once the count reaches zero. This is the main difference between a CyclicBarrier and CountDownLatch, which can be reused.

3. The getCount() method return the current count i.e. remaining threads which have not finished yet.

4. A thread can wait on latch by calling latch.await() method to start progress after remaining thread finishes their task.

5. One of the simplest use of CountDownLatch class is to block a thread until other threads have finished their jobs.

In our example, it was the main thread which was blocked by calling the await() method of CountDownLatch until all loader class finished their job i.e. downloaded courses from Udemy.


That's all about how to use CountDownLatch in Java. It's a useful concurrency utility which can be used to keep track of completion of tasks done by multiple threads. If you are writing a Java application which loads data from another system before start functioning e.g. accepting client connections, you can use CountDownLatch to keep track of download tasks.


Further Learning
Complete Java Masterclass
Multithreading and Parallel Computing in Java
Applying Concurrency and Multi-threading to Common Java Patterns
Java Concurrency in Practice - The book
Java Concurrency in Practice Course by Heinz Kabutz
CountDownLatch Java Documentation

Thanks a lot for reading this article so far. If you like this CountDownLatch example then please share with your friends and colleagues. If you have any questions or feedback then please drop a note.

No comments:

Post a Comment