CountDownLatch: Coordinating Thread Execution in Java

CountDownLatch: Coordinating Thread Execution in Java

When developing concurrent applications, there are often scenarios where you need to ensure multiple threads complete their tasks before proceeding to the next phase. Java's CountDownLatch utility provides an elegant solution for such synchronization requirements.

Consider a team collaboration scenario where team members must complete their individual tasks before the team can move forward with the next phase of the project. Each team member has different task complexities, resulting in varying completion times.

Team Collaboration Example

package com.example.concurrency;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class TeamProject {
    public static void main(String[] args) throws InterruptedException {
        int teamSize = 5;
        int taskComplexity = 0;
        Random random = new Random();
        
        // Latch to signal when the project starts
        CountDownLatch startLatch = new CountDownLatch(1);
        
        // Latch to wait for all team members to complete their tasks
        CountDownLatch completionLatch = new CountDownLatch(teamSize);
        
        // Create and start team member threads
        for(int i = 1; i <= teamSize; i++) {
            taskComplexity = random.nextInt(teamSize);
            new Thread(new TeamMember("member" + i, taskComplexity, startLatch, completionLatch)).start();
        }
        
        // Signal that the project has started
        System.out.println("*** Project Phase Begins ***");
        startLatch.countDown();
        
        // Wait for all team members to complete their tasks
        completionLatch.await();
        
        // Proceed to next phase
        System.out.println("All tasks completed. Moving to next phase...");
        System.out.println("*** Project Phase Ends ***");
    }
}

Team Member Implementation

package com.example.concurrency;
import java.util.concurrent.CountDownLatch;

public class TeamMember implements Runnable {
    private final String memberName;
    private final int taskDuration;
    private final CountDownLatch startLatch;
    private final CountDownLatch completionLatch;
    
    public TeamMember(String name, int duration, CountDownLatch startLatch, CountDownLatch completionLatch) {
        this.memberName = name;
        this.taskDuration = duration;
        this.startLatch = startLatch;
        this completionLatch = completionLatch;
    }
    
    @Override
    public void run() {
        try {
            // Wait for the project to start
            startLatch.await();
            
            // Perform the assigned task
            Thread.sleep(taskDuration * 1000);
            
            // Notify that the task is completed
            System.out.println(memberName + ": Task completed, waiting for other members.");
            completionLatch.countDown();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println(memberName + ": Task was interrupted.");
        }
    }
}

The CountDownLatch class is part of java.util.concurrent and provides a flexible mechanism for allowing one or more threads to wait for a set of operations to complete. The constructor takes an integer count that represents the number of times the countDown() method must be called before threads waiting on the latch can proceed.

In this example, we use two latches:

  1. The startLatch ensures all team members are ready before any of them begins their task.
  2. The completionLatch ensures the main thread waits until all team members have completed their tasks before proceeding to the next phase.

This pattern is particularly useful in scenarios where you need to coordinate the execution of multiple threads, ensuring that certain prerequisites are met before continuing with the program flow.

Tags: java Concurrency multithreading CountDownLatch Synchronization

Posted on Sun, 04 Oct 2026 16:13:03 +0000 by ericw