ForkJoinPool executes fork/join tasks with work stealing. A custom pool gives an application an explicit parallelism setting and a shutdown owner; the common pool is shared by unrelated code.
Java ForkJoinPool: own a custom pool and its shutdown
Operational contract
The method creates a four-worker pool for one CPU-bound calculation, invokes a result-bearing task, then shuts the pool down. Production services normally reuse an owned pool across many batches rather than creating one per call, but its lifecycle remains explicit. Shutdown stops new submissions; awaitTermination waits for existing work and can itself time out. On interruption, preserve the signal and request immediate shutdown. The task shown in the companion lesson stays CPU-bound; blocking I/O needs a different executor or a carefully bounded ManagedBlocker.
Failure case
A nightly shipment audit runs an isolated batch and then exits. It can own a pool for that batch. A long-running server should instead keep a service-owned pool and close it at service shutdown, because rebuilding workers on every HTTP request would waste resources. The four-worker setting is a starting capacity to measure, not a throughput promise.
Java code
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class ShipmentBatchRunner {
public static long sum(int[] quantities) throws InterruptedException {
ForkJoinPool workers = new ForkJoinPool(4);
try {
return workers.invoke(new ShipmentQuantitySum(quantities, 0, quantities.length));
} finally {
workers.shutdown();
try {
if (!workers.awaitTermination(3, TimeUnit.SECONDS)) workers.shutdownNow();
} catch (InterruptedException interrupted) {
workers.shutdownNow();
Thread.currentThread().interrupt();
throw interrupted;
}
}
}
}Performance and ownership cost
For an N-element sum, the pool still performs O(N) arithmetic; at most four configured workers can run its tasks concurrently. Starting and tearing down workers adds fixed overhead to each call. Reusing an owned pool amortizes that cost but requires a longer-lived shutdown owner.
Common Mistakes
- Do not shut down the common pool as if it belonged to one request.
- Do not create a new pool for each tiny calculation.
- Do not confuse shutdown with confirmation that every task has finished.
Connected lessons
- Java RecursiveTask: split work only above a measured threshold
- Java ExecutorService: bounded admission and shutdown
- Java cancellation: timed waits and cooperative interruption
- Java ManagedBlocker: declare a rare blocking wait to the pool
- Java fork/join failures: one failed task does not roll back sibling work
- Java parallel streams: reduce values instead of mutating shared results
- Java HTTP and fork/join decisions quiz
- Advanced Java
