CountDownLatch in Java

Use `CountDownLatch` in Java when one thread must wait for a fixed number of one-time events or worker completions.

10.3.3.1 CountDownLatch

Introduction to CountDownLatch

In the realm of Java concurrency, the CountDownLatch is a powerful synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. This utility is part of the java.util.concurrent package, which provides a rich set of tools for managing concurrent programming challenges. Understanding CountDownLatch is crucial for developers aiming to build robust, efficient, and thread-safe applications.

How CountDownLatch Works

The CountDownLatch operates by maintaining a count, which is initialized through its constructor. Threads can wait for this count to reach zero by invoking the await() method. Meanwhile, other threads can decrease the count by calling the countDown() method. Once the count reaches zero, all waiting threads are released and can proceed with their execution.

Key Methods

  • CountDownLatch(int count): Constructs a CountDownLatch initialized with the given count.
  • void await(): Causes the current thread to wait until the latch has counted down to zero.
  • void countDown(): Decreases the count of the latch, releasing all waiting threads if the count reaches zero.
  • long getCount(): Returns the current count.

Typical Use Cases

CountDownLatch is particularly useful in scenarios where a thread needs to wait for multiple operations to complete before proceeding. Common use cases include:

  • Starting a service only after all prerequisites are ready: For instance, a server might wait for multiple configuration files to be loaded before starting.
  • Waiting for multiple threads to complete: In a testing environment, a main thread might wait for several worker threads to finish processing before aggregating results.
  • Simulating concurrent activities: Useful in testing scenarios where you need to simulate multiple threads starting at the same time.

Code Example: Using CountDownLatch

Consider a scenario where a main thread waits for three worker threads to complete their tasks before proceeding.

 1import java.util.concurrent.CountDownLatch;
 2
 3public class CountDownLatchExample {
 4    public static void main(String[] args) {
 5        final int numberOfWorkers = 3;
 6        CountDownLatch latch = new CountDownLatch(numberOfWorkers);
 7
 8        for (int i = 0; i < numberOfWorkers; i++) {
 9            new Thread(new Worker(latch)).start();
10        }
11
12        try {
13            System.out.println("Main thread waiting for workers to complete...");
14            latch.await(); // Main thread waits here
15            System.out.println("All workers have completed. Main thread proceeding.");
16        } catch (InterruptedException e) {
17            e.printStackTrace();
18        }
19    }
20}
21
22class Worker implements Runnable {
23    private final CountDownLatch latch;
24
25    public Worker(CountDownLatch latch) {
26        this.latch = latch;
27    }
28
29    @Override
30    public void run() {
31        try {
32            // Simulate work
33            System.out.println(Thread.currentThread().getName() + " is working...");
34            Thread.sleep((long) (Math.random() * 1000));
35            System.out.println(Thread.currentThread().getName() + " has finished.");
36        } catch (InterruptedException e) {
37            e.printStackTrace();
38        } finally {
39            latch.countDown(); // Decrement the count of the latch
40        }
41    }
42}

Best Practices

  • Ensure the Latch Count Reaches Zero: Always ensure that the countDown() method is called the correct number of times to prevent deadlocks. This is typically done in a finally block to ensure it executes even if an exception occurs.
  • Avoid Reusing CountDownLatch: A CountDownLatch is a one-time-use object. Once the count reaches zero, it cannot be reset or reused.
  • Consider Thread Interruption: Handle InterruptedException appropriately, especially when using the await() method.

Differences Between CountDownLatch and Other Synchronization Tools

CountDownLatch vs. CyclicBarrier

  • CountDownLatch: Allows threads to wait for a set of operations to complete. It cannot be reused once the count reaches zero.
  • CyclicBarrier: Allows a set of threads to wait for each other to reach a common barrier point. It can be reused after the barrier is broken.

CountDownLatch vs. Semaphore

  • CountDownLatch: Used for waiting for a set of operations to complete.
  • Semaphore: Controls access to a resource by multiple threads, allowing a specified number of threads to access the resource concurrently.

Visualizing CountDownLatch

To better understand the workflow of CountDownLatch, consider the following sequence diagram:

    sequenceDiagram
	    participant MainThread
	    participant Worker1
	    participant Worker2
	    participant Worker3
	
	    MainThread->>Worker1: Start
	    MainThread->>Worker2: Start
	    MainThread->>Worker3: Start
	    MainThread->>MainThread: await()
	    
	    Worker1->>Worker1: Perform Task
	    Worker1->>MainThread: countDown()
	    
	    Worker2->>Worker2: Perform Task
	    Worker2->>MainThread: countDown()
	    
	    Worker3->>Worker3: Perform Task
	    Worker3->>MainThread: countDown()
	    
	    MainThread->>MainThread: Proceed

Diagram Explanation: The diagram illustrates the main thread starting three worker threads and then waiting for all of them to complete their tasks. Each worker thread performs its task and calls countDown(). Once all worker threads have called countDown(), the main thread proceeds.

Sample Use Cases

  • Batch Processing: In a batch processing system, CountDownLatch can be used to ensure that all batch jobs are completed before generating a summary report.
  • Parallel Initialization: When initializing a complex system, use CountDownLatch to ensure all components are initialized before starting the system.
  • 6.6 Singleton Pattern: Often used in conjunction with CountDownLatch to ensure a single instance of a resource is initialized after all prerequisites are met.
  • Barrier Synchronization: Similar to CyclicBarrier, which is used when threads must wait for each other at a common point.

Known Uses

  • Java Concurrency Framework: The CountDownLatch is widely used in Java’s concurrency framework for managing thread synchronization.
  • Testing Frameworks: Often used in testing frameworks to simulate concurrent user actions and wait for all actions to complete before asserting results.

Conclusion

The CountDownLatch is an essential tool in the Java concurrency toolkit, providing a simple yet powerful mechanism for synchronizing threads. By understanding its workings, use cases, and best practices, developers can effectively manage complex multithreading scenarios, ensuring that operations are completed in a controlled and predictable manner.


Test Your Knowledge: CountDownLatch in Java Concurrency

Loading quiz…
Revised on Thursday, April 23, 2026