package com.packt.tfesenko.multithreading.section1; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; import java.util.stream.IntStream; public class Lesson3 { public static void main(String[] args) { AppleTree[] appleTrees = AppleTree.newTreeGarden(12); ForkJoinPool pool = ForkJoinPool.commonPool(); PickFruitTask task = new PickFruitTask(appleTrees, 0, appleTrees.length - 1); int result = pool.invoke(task); System.out.println(); System.out.println("Total apples picked: " + result); } public static class PickFruitTask extends RecursiveTask<Integer> { private final AppleTree[] appleTrees; private final int startInclusive; private final int endInclusive; private final int taskThreadshold = 4; public PickFruitTask(AppleTree[] array, int startInclusive, int endInclusive) { this.appleTrees = array; this.startInclusive = startInclusive; this.endInclusive = endInclusive; } @Override protected Integer compute() { if (endInclusive - startInclusive < taskThreadshold) { return doCompute(); } int midpoint = startInclusive + (endInclusive - startInclusive) / 2; PickFruitTask leftSum = new PickFruitTask(appleTrees, startInclusive, midpoint); PickFruitTask rightSum = new PickFruitTask(appleTrees, midpoint + 1, endInclusive); rightSum.fork(); // computed asynchronously return leftSum.compute()// computed synchronously: immediately and in the current thread + rightSum.join(); } protected Integer doCompute() { return IntStream.rangeClosed(startInclusive, endInclusive)// .map(i -> appleTrees[i].pickApples())// .sum(); // Equivalent with a "for" loop :) // int result = 0; // for (int i = startInclusive; i <= endInclusive; i++) { // result += array[i].pickApples(); // } // return result; } } }