Fork/join and parallel streams question 103 of 180 mid
What is the correct shape of a RecursiveTask?
- Fork both halves, then join both
- Correct: Fork one half, compute the other on the current thread, then join:
left.fork(); right.compute(); left.join(); - Call
invoke()on both halves - Submit both halves to the common pool
protected Long compute() {
if (hi - lo <= THRESHOLD) {
return computeDirectly();
}
int mid = (lo + hi) >>> 1;
SumTask left = new SumTask(array, lo, mid);
left.fork(); // hand one half to the pool
long rightResult = new SumTask(array, mid, hi).compute(); // do the other here
return rightResult + left.join(); // then collect
}
Forking both halves and joining both wastes the current thread, which sits idle while two other threads work. The order matters too: fork, then compute, then join. Joining before computing the second half serialises the whole thing.
The threshold is the other half of the answer. Too small and the splitting overhead dominates; the usual starting point is a few thousand elements of simple work, tuned by measurement.
Quiz yourself on Fork/join and parallel streams Suggest a correction