Mastering Java’s Future Pattern: From CountDownLatch to Callable

This article explains Java’s asynchronous call mechanisms, reviews thread counters like CountDownLatch, introduces the Future pattern with its core roles and structure, provides a step‑by‑step code implementation, and shows how the JDK implements Future using Callable and FutureTask.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Mastering Java’s Future Pattern: From CountDownLatch to Callable

Java Multithreading – (18) Deep Dive into Condition Interface and Wait/Notify Pattern

1. Thread Counter Review

We revisit the use of CountDownLatch as a thread counter that blocks the main thread with countDownLatch.await() until all worker threads finish, similar to an asynchronous call.

2. What Is Asynchronous Call?

An asynchronous call returns immediately, allowing the caller to perform other work while the callee processes the request in the background; the result is later obtained at a designated blocking point, embodying the core idea of the Future pattern.

3. Future Pattern

The Future pattern returns a contract that can later provide the required data. It enables the client to continue other tasks while waiting for a time‑consuming operation to finish, improving overall system efficiency.

The diagram shows a serial program where a long‑running task blocks all subsequent tasks, contrasted with the Future flow where a placeholder is returned instantly and the real result is fetched later.

4. Simple Implementation of the Future Pattern

The implementation consists of five classes: Data interface, FutureData, RealData, Client, and Main. The following images illustrate each component.

Execution result:

5. JDK’s Future Implementation

The JDK provides built‑in support for the Future pattern. The RealData class implements Callable and overrides call() to perform a time‑consuming operation.

Creating a

FutureTask<String> futureTask = new FutureTask<>(new RealData("Hello"))

constructs a task with a return value. FutureTask implements RunnableFuture, which extends both Future and Runnable, allowing it to be submitted to an Executor.

Two constructors are available: one accepting a Callable and another accepting a Runnable. The latter is adapted to a Callable via Executors.callable(), enabling result retrieval and cancellation features.

Callable provides a return value and methods such as get(), isDone(), and cancel(), distinguishing it from Runnable which lacks a result.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentconcurrencyCallableFuture
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

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.