Backend Development 6 min read

Understanding CountDownLatch and CompletableFuture in Java Concurrency

This article explains the purpose, typical usage scenarios, and provides concrete code demonstrations of Java's CountDownLatch and CompletableFuture, comparing their synchronization versus asynchronous capabilities and guiding developers on selecting the appropriate tool for effective multithreaded programming.

Top Architecture Tech Stack
Top Architecture Tech Stack
Top Architecture Tech Stack
Understanding CountDownLatch and CompletableFuture in Java Concurrency

In the world of Java concurrent programming, CountDownLatch and CompletableFuture are two essential utilities that help manage and coordinate the execution of multiple threads.

CountDownLatch

Imagine you are a project manager waiting for several teams to finish their tasks before proceeding. In Java, CountDownLatch acts as a helper that uses a counter to control when waiting threads are released. The counter is initialized with the number of threads to wait for, each thread decrements the counter when it finishes, and when the counter reaches zero all waiting threads continue.

Code Example

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        final int totalThreads = 3;
        CountDownLatch latch = new CountDownLatch(totalThreads);

        for (int i = 0; i < totalThreads; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " 正在工作");
                try {
                    Thread.sleep(1000); // 模拟工作
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 完成工作");
                latch.countDown(); // 计数减一
            }).start();
        }

        System.out.println("主线程等待所有子线程完成");
        latch.await(); // 等待计数器为零
        System.out.println("所有子线程完成,主线程继续执行");
    }
}

The main thread waits until the three worker threads finish their simulated work before proceeding.

CompletableFuture: The Swiss Army Knife of Asynchronous Programming

Java 8 introduced CompletableFuture , a powerful tool for asynchronous programming. It supports fluent chaining, handling of asynchronous results, and easy composition of multiple asynchronous tasks.

Code Example

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        CompletableFuture
future = CompletableFuture.runAsync(() -> {
            System.out.println("异步任务1执行");
        }, executor)
        .thenRunAsync(() -> {
            System.out.println("异步任务2执行");
        }, executor);

        future.join(); // 等待异步任务完成
        executor.shutdown();
    }
}

This example creates two asynchronous tasks that execute sequentially on a fixed‑size thread pool.

Differences

Both CountDownLatch and CompletableFuture are Java concurrency tools, but they serve different purposes.

CountDownLatch

Main Features:

Works with a counter initialized to a specific value.

The countDown() method decrements the counter.

The await() method blocks until the counter reaches zero.

Typical Use Cases: Waiting for a group of operations to complete before proceeding.

CompletableFuture

Main Features:

Executes tasks asynchronously.

Supports callbacks that run when a task completes.

Allows composition of multiple asynchronous tasks.

Typical Use Cases: Asynchronous programming where tasks need to be chained or combined.

Summary

CountDownLatch is used for synchronously waiting for a set of operations to finish, while CompletableFuture is used for asynchronous programming and task composition.

CountDownLatch generally provides simple synchronization, whereas CompletableFuture offers richer features such as exception handling and task combination.

Choosing the right tool depends on whether you need a blocking wait (use CountDownLatch ) or a non‑blocking, composable asynchronous workflow (use CompletableFuture ).

JavaconcurrencyCompletableFuturemultithreadingCountDownLatch
Top Architecture Tech Stack
Written by

Top Architecture Tech Stack

Sharing Java and Python tech insights, with occasional practical development tool tips.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.