import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ArraySummerForkJoin {
// Extend RecursiveTask for tasks that return a result
static class SummingRecursiveTask extends RecursiveTask {
private static final int THRESHOLD = 10_000; // Threshold for direct computation
private final int[] arr;
private final int start;
private final int end;
public SummingRecursiveTask(int[] arr, int start, int end) {
this.arr = arr;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
int length = end - start;
if (length <= THRESHOLD) {
// Base case: if the chunk is small enough, compute directly
long partialSum = 0;
for (int i = start; i < end; i++) {
partialSum += arr[i];
}
return partialSum;
} else {
// Recursive step: split the task into two sub-tasks
int mid = start + length / 2;
SummingRecursiveTask leftTask = new SummingRecursiveTask(arr, start, mid);
SummingRecursiveTask rightTask = new SummingRecursiveTask(arr, mid, end);
// Fork the left task to run asynchronously
leftTask.fork();
// Compute the right task (or fork it too) and then join the left
long rightResult = rightTask.compute(); // Or rightTask.fork(); then rightTask.join();
long leftResult = leftTask.join(); // Wait for the left task to complete and get its result
return leftResult + rightResult;
}
}
}
public static long sumForkJoin(int[] arr) {
// Create a ForkJoinPool
ForkJoinPool forkJoinPool = new ForkJoinPool(); // By default uses availableProcessors() threads
SummingRecursiveTask mainTask = new SummingRecursiveTask(arr, 0, arr.length);
long totalSum = forkJoinPool.invoke(mainTask); // Invoke the main task and wait for its completion
forkJoinPool.shutdown(); // Important: Shut down the pool
return totalSum;
}
public static void main(String[] args) {
int arraySize = 1_000_000;
int[] largeArray = new int[arraySize];
for (int i = 0; i < arraySize; i++) {
largeArray[i] = i % 100;
}
long startTime = System.nanoTime();
long sum = sumForkJoin(largeArray);
long endTime = System.nanoTime();
System.out.println("Multi-threaded (Fork/Join) sum: " + sum);
System.out.println("Multi-threaded (Fork/Join) time: " + (endTime - startTime) / 1_000_000.0 + " ms");
}
}