Analyzing JDK 1.8 FutureTask Source Code
This article provides a detailed analysis of JDK 1.8’s FutureTask implementation, explaining its purpose, usage examples, internal structure, state transitions, key methods such as run, get, cancel, and the concurrency mechanisms like volatile fields, CAS operations, and thread‑waiting queues.
The article introduces the JDK 1.8 source‑code‑analysis project (with Chinese comments) and focuses on the FutureTask class, a core component for asynchronous task execution in Java.
What is Future?
Future acts like an order number for a long‑running task: you start the task in a separate thread, continue other work, and later retrieve the result using the Future "ticket".
How to use Future
A simple example demonstrates creating a FutureTask<String> with a Callable that simulates boiling water, starting it in a new thread, doing other work (preparing hot‑pot ingredients), and finally obtaining the result with futureTask.get() .
public class DaHuoGuo {
public static void main(String[] args) throws Exception {
FutureTask
futureTask = new FutureTask<>(new Callable
() {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + ":开始烧开水...");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + ":开水已经烧好了...");
return "开水";
}
});
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(Thread.currentThread().getName() + ":此时开启了一个线程执行future的逻辑(烧开水),此时我们可以干点别的事情(比如准备火锅食材)...");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + ":火锅食材准备好了");
String boilWater = futureTask.get();
System.out.println(Thread.currentThread().getName() + ":" + boilWater + "和火锅食材已经准备好,我们可以开始打火锅啦");
}
}FutureTask Class Structure
The class implements RunnableFuture , which extends both Future and Runnable . Key fields include:
private Callable
callable; // the task
private Object outcome; // result or exception
private volatile Thread runner; // thread executing the task
private volatile WaitNode waiters; // waiting threads
private volatile int state; // task state
static final int NEW = 0, COMPLETING = 1, NORMAL = 2, EXCEPTIONAL = 3,
CANCELLED = 4, INTERRUPTING = 5, INTERRUPTED = 6;Two constructors allow creating a FutureTask from a Callable or from a Runnable plus a predefined result.
run() Method
The overridden run() method ensures only one thread can execute the task (using CAS on runner ), invokes the Callable , captures the result or exception, updates the state (NEW → COMPLETING → NORMAL/EXCEPTIONAL), clears runner , and finally calls finishCompletion() to wake waiting threads.
Result Handling – set() and setException()
Both methods use CAS to transition from NEW to COMPLETING, store the outcome, set the final state (NORMAL or EXCEPTIONAL), and invoke finishCompletion() .
finishCompletion()
Wakes all threads in the wait‑queue (a Treiber stack) via LockSupport.unpark , calls done() , and clears the callable reference to reduce memory footprint.
awaitDone() and get()
FutureTask.get() checks the state; if the task is still running (state ≤ COMPLETING) it calls awaitDone(false, 0L) , which repeatedly parks the calling thread until the task completes, handling interruption and optional timeout.
cancel() Method
Attempts to change the state from NEW to either CANCELLED or INTERRUPTING (if mayInterruptIfRunning is true). When interruption is requested, the runner thread is interrupted and the state is set to INTERRUPTED . In all cases finishCompletion() is invoked, causing any waiting get() calls to receive a CancellationException even if the task later finishes normally.
Key Takeaways
Use of volatile and Unsafe.compareAndSwap provides lock‑free thread safety.
State machine (NEW, COMPLETING, NORMAL, EXCEPTIONAL, CANCELLED, INTERRUPTING, INTERRUPTED) drives all transitions.
Waiting threads are managed via a lock‑free stack and LockSupport for efficient blocking/unblocking.
Cancellation only signals interruption; it does not forcibly stop the task.
The article concludes with a list of practical lessons for developers writing concurrent frameworks, such as leveraging LockSupport , volatile fields, CAS, and careful state management.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
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.