CompletableFuture.cancel completes an unfinished future with CancellationException; it does not control the computation that might have produced that future.
Java CompletableFuture cancellation: distinguish result status from worker interruption
Operational contract
The method cancels a future handed to it and reports whether this call changed its state. The mayInterruptIfRunning argument has no effect for CompletableFuture itself. A producer that owns an HTTP request, thread, or database statement needs a separate cancellation hook. Unfinished dependent stages become exceptional. Calling cancel on an already completed future does not retract its result, and canceling one stage is not a general cascade to every upstream operation.
Failure case
A caller times out a receipt request and cancels its result future. A network operation started elsewhere can still complete and consume a connection. Its owner must close or cancel that operation under a separate resource policy.
Java code
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
public class ReceiptCancellationBoundary {
public static boolean abandonResult(CompletableFuture<String> receipt) {
Objects.requireNonNull(receipt);
return receipt.cancel(true);
}
}Performance and ownership cost
Cancellation changes O(1) future state, plus completion work for dependent stages. It saves no predictable CPU or I/O by itself because producer interruption and resource cleanup are outside this future's control.
Common Mistakes
- Do not assume cancel(true) interrupts the producer of a CompletableFuture.
- Do not equate an abandoned result with released sockets or database resources.
- Do not rely on cancellation to undo side effects.
