As usual before I move 5 steps in my thought process, industry will move 50 steps. No wonder, we have solve for this in Java 7.
It's the fork/join framework is an implementation of the
ExecutorService
interface that helps you take advantage of multiple processors. As with any ExecutorService
, the fork/join framework distributes tasks to worker threads in a thread pool. The fork/join framework is distinct because it uses a work-stealing algorithm. Worker threads that run out of things to do can steal tasks from other threads that are still busy.If you are not using Java 7 you also need to have "jsr166y.jar" in the classpath.
package com.sarav.forkjoin; import java.util.Random;RecrusiveAction implementationpublic class Problem {private final int[] list = new int[2000000]; public Problem() { Random generator = new Random(19580427); for (int i = 0; i < list.length; i++) { list[i] = generator.nextInt(500000); } } public int[] getList() { return list; } }
package com.sarav.forkjoin; import java.util.Arrays; import jsr166y.forkjoin.RecursiveAction; public class Solver extends RecursiveAction { private int[] list; public long result; public Solver(int[] array) { this.list = array; } @Override protected void compute() { if (list.length == 1) { result = list[0]; } else { int midpoint = list.length / 2; int[] l1 = Arrays.copyOfRange(list, 0, midpoint); int[] l2 = Arrays.copyOfRange(list, midpoint, list.length); Solver s1 = new Solver(l1); Solver s2 = new Solver(l2); forkJoin(s1, s2); result = s1.result + s2.result; } } }Test to verify my understanding
package com.sarav.forkjoin.testing; import jsr166y.forkjoin.ForkJoinExecutor; import jsr166y.forkjoin.ForkJoinPool; import com.sarav.forkjoin.Problem; import com.sarav.forkjoin.Solver; public class Test { public static void main(String[] args) { Problem test = new Problem(); // Check the number of available processors int nThreads = Runtime.getRuntime().availableProcessors(); System.out.println(nThreads); Solver mfj = new Solver(test.getList()); ForkJoinExecutor pool = new ForkJoinPool(nThreads); pool.invoke(mfj); long result = mfj.getResult(); System.out.println("Done. Result: " + result); long sum = 0; // Check if the result was ok for (int i = 0; i < test.getList().length; i++) { sum += test.getList()[i]; } System.out.println("Done. Result: " + sum); } }
I didn't apply this in my real time application to give some performance report. Soon I will :)