Java
Multithreading
CountDownLatch
Concurrency
Java Programming

How is CountDownLatch used in Java Multithreading?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In the realm of Java multithreading, synchronization mechanisms are vital to ensure that threads cooperate and execute predictably. One such synchronization aid is CountDownLatch, which belongs to the java.util.concurrent package. This article delves into how CountDownLatch functions, its applications, and the scenarios where it proves beneficial.

Understanding CountDownLatch

CountDownLatch is a versatile synchronization tool that allows one or more threads to wait until a set of operations being performed by other threads completes. It's constructed with an integral count value. This count is decremented by calls to the countDown() method. Once the count reaches zero, any threads waiting through the await() method are released. The latch cannot be reset after the count has reached zero, which distinguishes it from other synchronization constructs like CyclicBarrier.

The CountDownLatch can be seen as a gate. This gate remains closed until all the events complete, after which it opens and allows the waiting threads to proceed.

Basic API

Here are the key methods of CountDownLatch:

  • CountDownLatch(int count): Constructor that initializes the latch with the given count.
  • void await(): Causes the current thread to wait until the latch has counted down to zero.
  • boolean await(long timeout, TimeUnit unit): Similar to await(), but with a timeout period.
  • void countDown(): Decrements the count of the latch, releasing all waiting threads if the count reaches zero.
  • long getCount(): Returns the current count.

Usage Example

Consider a scenario where we have to initialize multiple services (say, network, database, cache, etc.) before an application can start. We can use CountDownLatch to ensure that the main application thread waits for all services to initialize.

java
1import java.util.concurrent.CountDownLatch;
2
3public class ServiceInitializer {
4
5    private static final int NUMBER_OF_SERVICES = 3;
6
7    public static void main(String[] args) throws InterruptedException {
8        CountDownLatch latch = new CountDownLatch(NUMBER_OF_SERVICES);
9
10        Thread service1 = new Thread(new Service("Network Service", latch));
11        Thread service2 = new Thread(new Service("Database Service", latch));
12        Thread service3 = new Thread(new Service("Cache Service", latch));
13
14        service1.start();
15        service2.start();
16        service3.start();
17
18        // The main thread will wait until the latch count becomes zero
19        latch.await();
20
21        System.out.println("All services are initialized, starting the main application thread.");
22    }
23}
24
25class Service implements Runnable {
26    private final String serviceName;
27    private final CountDownLatch latch;
28
29    public Service(String serviceName, CountDownLatch latch) {
30        this.serviceName = serviceName;
31        this.latch = latch;
32    }
33
34    @Override
35    public void run() {
36        try {
37            // Simulate service initialization
38            Thread.sleep((long) (Math.random() * 1000));
39            System.out.println(serviceName + " is initialized.");
40
41        } catch (InterruptedException e) {
42            Thread.currentThread().interrupt();
43        } finally {
44            // Count down the latch
45            latch.countDown();
46        }
47    }
48}

Table Summary

FeatureDescription
PurposeAllows threads to wait for other threads to complete specific operations.
Key Methodsawait(), countDown(), getCount().
Usage ScenarioWaiting for multiple services/threads to complete initialization before continuing.
Once ZeroThe latch cannot be reset or reused.
Design PatternFits the "latch" pattern - gates remain closed until all prerequisites are met.

Advanced Usage Scenarios

1. One-time Events

CountDownLatch is well-suited to handle one-time events, such as initializing resources during application startup, as shown in the example above. Each service initializes, notifying the latch, and once every service has completed, the main thread is notified to proceed.

2. Task Coordination

In scenarios where multiple computations need to start simultaneously but only when a specific requirement or computation completes, CountDownLatch ensures that worker threads wait for the signal indicating that they're ready to proceed with their calculations.

3. Test Parallelism

In testing environments, CountDownLatch can control parallel execution and synchronization, ensuring that tests run and complete correctly as expected.

Conclusion

The CountDownLatch is a straightforward yet powerful synchronization tool in Java for managing multiple thread completion. It facilitates easier multi-threading programming, especially in initialization or prerequisite satisfaction scenarios. However, since it cannot be reused or reset, choosing between CountDownLatch and other concurrency constructs like CyclicBarrier should depend on the specific requirements of your application.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.