Computing the sum via RecursiveTask

To demonstrate the forking behavior of the framework, let's assume that we have a list of numbers and we want to compute the sum of these numbers. For this, we recursively split (fork) this list as long as it is larger than the specified THRESHOLD using the createSubtasks() method. Each task is added into List<SumRecursiveTask>. In the end, this list is submitted to ForkJoinPool via the invokeAll​(Collection<T> tasks) method. This is done using the following code:

public class SumRecursiveTask extends RecursiveTask<Integer> {

private static final Logger logger
= Logger.getLogger(SumRecursiveTask.class.getName());
private static final int THRESHOLD = 10;

private final List<Integer> worklist;

public SumRecursiveTask(List<Integer> worklist) {
this.worklist = worklist;
}

@Override
protected Integer compute() {
if (worklist.size() <= THRESHOLD) {
return partialSum(worklist);
}

return ForkJoinTask.invokeAll(createSubtasks())
.stream()
.mapToInt(ForkJoinTask::join)
.sum();
}

private List<SumRecursiveTask> createSubtasks() {

List<SumRecursiveTask> subtasks = new ArrayList<>();
int size = worklist.size();

List<Integer> worklistLeft
= worklist.subList(0, (size + 1) / 2);
List<Integer> worklistRight
= worklist.subList((size + 1) / 2, size);

subtasks.add(new SumRecursiveTask(worklistLeft));
subtasks.add(new SumRecursiveTask(worklistRight));

return subtasks;
}

private Integer partialSum(List<Integer> worklist) {

int sum = worklist.stream()
.mapToInt(e -> e)
.sum();

logger.info(() -> "Partial sum: " + worklist + " = "
+ sum + " Thread: " + Thread.currentThread().getName());

return sum;
}
}

In order to test it, we need a list and ForkJoinPool as follows:

ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();

Random rnd = new Random();
List<Integer> list = new ArrayList<>();

for (int i = 0; i < 200; i++) {
list.add(1 + rnd.nextInt(10));
}

SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);

logger.info(() -> "Final sum: " + sumAll);

A possible output will be the following:

...
[15:17:06] Partial sum: [1, 3, 6, 6, 2, 5, 9] = 32
ForkJoinPool.commonPool-worker-9
...
[15:17:06] Partial sum: [1, 9, 9, 8, 9, 5] = 41
ForkJoinPool.commonPool-worker-7
[15:17:06] Final sum: 1084
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.249.42