Given the following incorrect program:
<code>
class MyTask extends RecursiveTask<Integer> {
final int low;
final int high;
static final int THRESHOLD = /* . . . */
MyTask (int low, int high) { this.low = low; this.high = high; }
Integer computeDirectly()/* . . . */
protected void compute() {
if (high low <= THRESHOLD)
return computeDirectly();
int mid = (low + high) / 2;
invokeAll(new MyTask(low, mid), new MyTask(mid, high));
</code>
Which two changes make the program work correctly?
A.
Results must be retrieved from the newly created MyTask Instances and combined.
B.
The THRESHOLD value must be increased so that the overhead of task creation does not dominate the cost of computation.
C.
The midpoint computation must be altered so that it splits the workload in an optimal manner.
D.
The compute () method must be changed to return an Integer result.
E.
The computeDirectly () method must be enhanced to fork () newly created tasks.
F.
The MyTask class must be modified to extend RecursiveAction instead of RecursiveTask.
Explanation:
D: the compute() method must return a result.
A: These results must be combined (in the lineinvokeAll(new MyTask(low, mid), new MyTask(mid,
high));)
Note 1:A RecursiveTask is a recursive result-bearing ForkJoinTask.
Note 2: The invokeAll(ForkJoinTask<?>… tasks) forks the given tasks, returning when isDone holds for each task or an (unchecked) exception is encountered, in which case the exception is rethrown.
Note 3: Using the fork/join framework is simple. The first step is to write some code that performs a segment of the work. Your code should look similar to this:
if (my portion of the work is small enough)
do the work directly
else
split my work into two pieces
invoke the two pieces and wait for the resultsWrap this code as a ForkJoinTask subclass, typically as one of its more specialized types RecursiveTask(which can return a result) or RecursiveAction.