Java Fork/Join


This framework is an implementation of the ExecutionService interface, which helps to take advantage of the multiple processors.
Designed for work that can be  broken into small pieces recursively.
The GOAL is to utilize processing power to improve the performance of the applications.

Distribute tasks to worker threads in a thread pool, and uses a work-stealing algorithm.
If a worker thread is out of work it can steal tasks from other thread which are still busy.

How to use:








Important Classes/Interfaces 
  • RecursiveTask
  • RecursiveAction
  • ForkJoinPool
Example

 /*  
  * To change this license header, choose License Headers in Project Properties.  
  * To change this template file, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package com.lrajeew.base;  
 import java.util.concurrent.RecursiveAction;  
 /**  
  *  
  * @author lananda  
  */  
 public class ForkBlur extends RecursiveAction{  
   private int[] mSource;  
   private int mStart;  
   private int mLength;  
   private int[] mDestination;  
   // Processing window size; should be odd.  
   private int mBlurWidth = 15;  
   protected static int sThreshold = 100000;  
   private static int slices = 2;  
   public ForkBlur(int[] src, int start, int length, int[] dst) {  
     mSource = src;  
     mStart = start;  
     mLength = length;  
     mDestination = dst;  
   }  
   @Override  
   protected void compute() {  
     if (mLength < sThreshold) {  
     computeDirectly();  
     return;  
   }  
   int split = mLength / slices;  
   invokeAll(new ForkBlur(mSource, mStart, split, mDestination),  
        new ForkBlur(mSource, mStart + split, mLength - split,  
               mDestination));  
   }  
   protected void computeDirectly() {  
     int sidePixels = (mBlurWidth - 1) / 2;  
     for (int index = mStart; index < mStart + mLength; index++) {  
       // Calculate average.  
       float rt = 0, gt = 0, bt = 0;  
       for (int mi = -sidePixels; mi <= sidePixels; mi++) {  
         int mindex = Math.min(Math.max(mi + index, 0),  
                   mSource.length - 1);  
         int pixel = mSource[mindex];  
         rt += (float)((pixel & 0x00ff0000) >> 16)  
            / mBlurWidth;  
         gt += (float)((pixel & 0x0000ff00) >> 8)  
            / mBlurWidth;  
         bt += (float)((pixel & 0x000000ff) >> 0)  
            / mBlurWidth;  
       }  
       // Reassemble destination pixel.  
       int dpixel = (0xff000000   ) |  
           (((int)rt) << 16) |  
           (((int)gt) << 8) |  
           (((int)bt) << 0);  
       mDestination[index] = dpixel;  
     }  
   }  
 }  


Executor


 /*  
  * To change this license header, choose License Headers in Project Properties.  
  * To change this template file, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package com.lrajeew.base;  
 import java.util.concurrent.ForkJoinPool;  
 /**  
  *  
  * @author lananda  
  */  
 public class BlurImage {  
   public static void main(String... args){  
     int[] src = {1,2,4,5,6,7,8,9,1};  
     int[] dst = {2,3,1,4,2,4,5,6,7};  
//Create a task that represents all of the work to be done.
     ForkBlur fb = new ForkBlur(src, 0, src.length, dst);  
//Create the ForkJoinPool that will run the task.
     ForkJoinPool pool = new ForkJoinPool();  
//Run the task.
     pool.invoke(fb);  
   }  
 }  

In Java 8, java.util.Arrays class for its parallelSort() uses the above mechanism.

Comments