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 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
