import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class ForkJoinPractice {
public ForkJoinPractice() {
}
public static void main(String[] args) {
final int size = 200000000;
final int[] numbers = new int[size];
for (int i = 0; i < size; i++) {
numbers[i] = i;
}
int threshold = size / 8;
int nThreads = 2;
SelectMaxProblem problem = new SelectMaxProblem(numbers, 0, size);
MaxFJ mfj = new MaxFJ(problem, threshold);
ForkJoinPool fjp = new ForkJoinPool(nThreads);
final long start = System.nanoTime();
fjp.invoke(mfj);
final long mfjElapsed = System.nanoTime() - start;
System.out.println("Result = " + mfj.result + ", elapsed nanos = " + mfjElapsed);
MaxSerial serial = new MaxSerial(problem);
final long startSerial = System.nanoTime();
serial.compute();
final long serialElapsed = System.nanoTime() - startSerial;
System.out.println("Result = " + serial.result + ", elapsed nanos = " + serialElapsed);
}
private static class MaxFJ extends RecursiveAction {
private final int threshold;
public double result;
private final SelectMaxProblem problem;
private MaxFJ(final SelectMaxProblem problem, final int threshold) {
this.threshold = threshold;
this.problem = problem;
}
public void compute() {
if (problem.size < threshold) {
MaxSerial serialSolve = new MaxSerial(problem);
serialSolve.compute();
result = serialSolve.result;
// System.out.println("Serial result = " + result);
} else {
int midpoint = problem.start + problem.size / 2;
MaxFJ left = new MaxFJ(problem.subproblem(problem.start, midpoint), threshold);
MaxFJ right = new MaxFJ(problem.subproblem(midpoint,
problem.end), threshold);
left.fork();
right.compute();
left.join();
result = Math.max(left.result, right.result);
}
}
}
private static class MaxSerial {
public double result;
private final SelectMaxProblem problem;
private MaxSerial(final SelectMaxProblem problem) {
this.problem = problem;
}
private void compute() {
for (int i = problem.start; i < problem.end; i++) {
if (Math.log(problem.numbers[i]) > result) {
result = Math.log(problem.numbers[i]);
}
}
}
}
public static class SelectMaxProblem {
private final int[] numbers;
private final int start;
private final int end;
public final int size;
private SelectMaxProblem(final int[] numbers, final int start, final int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
this.size = end - start;
}
private SelectMaxProblem subproblem(final int subStart, final int subEnd) {
return new SelectMaxProblem(numbers, subStart, subEnd);
}
}
}