Both are the abstract task types you subclass for fork/join work: RecursiveTask<V> returns a result from compute(), while RecursiveAction returns nothing (void). Pick RecursiveTask when you compute and combine a value (a sum, a count, a merged list); pick RecursiveAction for in-place work with no return (sorting a sub-array, applying a transform to a slice).
The fork/compute/join idiom
The body of compute() follows one shape: a base case below a threshold, and a recursive case that splits, forks one half, computes the other inline, and joins.
class SumTask extends RecursiveTask<Long> {
private static final int THRESHOLD = 10_000;
private final long[] arr;
private final int lo, hi;
SumTask(long[] arr, int lo, int hi) { this.arr = arr; this.lo = lo; this.hi = hi; }
@Override
protected Long compute() {
if (hi - lo <= THRESHOLD) { // base case: solve directly
long sum = 0;
for (int i = lo; i < hi; i++) sum += arr[i];
return sum;
}
int mid = (lo + hi) >>> 1;
SumTask left = new SumTask(arr, lo, mid);
SumTask right = new SumTask(arr, mid, hi);
left.fork(); // schedule left asynchronously
long rightResult = right.compute(); // compute right in THIS thread
long leftResult = left.join(); // wait for / help run left
return leftResult + rightResult;
}
}
long total = ForkJoinPool.commonPool().invoke(new SumTask(data, 0, data.length));
The rules that matter
- Compute one side, fork the other. Calling
left.fork(); right.fork(); left.join(); right.join();wastes the current thread waiting. Computing one half inline keeps every worker productive. join()order: forked-last, joined-first isn't required, but compute the un-forked half before joining the forked one — that's the work-stealing-friendly pattern.- Pick a real threshold. Too small and you drown in task-creation and scheduling overhead; too large and you under-utilize cores. Aim for enough tasks to balance across workers (a common heuristic is ~10× the parallelism level) while each task does meaningful work.
- Never block on I/O or locks inside
compute()— it ties up a scarce worker.