Do you know ForkJoinPool Java 7?

Java 7 brings and/or improves thread management to handle heavy and complex tasks.

You can use threads, ExecutorServices and this: ForkJoinPool.

There is an increasing developers movement to coding in a functional state of mind, using Ruby, Scala, Clojure and other similar programming languages. Java 8 will follow this path too, with lambdas. If you are not using a functional approach in programming, I invite you to do so, its a very different way of thinking where the “divide to conquer” its a must!

In Java 7 you can use this way of thinking to resolve complicated problems, the ones where its necessary to think recursively where you can split a heavy task in simples ones, like when you are sorting a big list using quick sort, transverse a file system including every folder and file, etc. These are problems that seems complicated at first, but thinking recursively it turns out to be very simple tasks.

The main algorithm to implement a recursively task its always something like:

  1. What is the stop condition? (Here you return a “real” value)
  2. Call the method recursively calling it itself with some sort of improvement in the parameters, like if you are in a for.. loop.

For instance, long factorial(long n)

  1. stop condition: if( n <= 1) return 1;
  2. calling recursively like a loop: return n * factorial(n-1)

Has you know by now, the factorial(n-1) will have to stop in the future, because n-1 its decreasing until it reaches  n <= 1, and then n * <result> will be really calculated!

 

In Java 7 you have a Class ForkJoinPool that automatically handle threads to execute the smaller tasks like the above: n and  factorial(n-1).

The recursively method will always be the protected Long compute(), which must be an @override because the class will extend: RecursiveTask<T>, where <T> will be the return value of the compute method!

In the example below, I have implemented a very simple example to calculate the sum between 2 numbers, using recursive smaller tasks.

I start with some range, if the stop condition (end – start), its below 10, then I return the sum between the start and end, otherwise I split the range in 2 parts, the first one executes concurrently (using fork witch puts the thread in the ForkJoinPool) the second half of (end – start) and the first one computes the sum delegating its execution to the compute method (itself!), or the other half.

Observe the last return: return t2.compute() + t1.join(); where the second thread calls the compute and then waits for the fork previously executed as the first thread!

import java.util.concurrent.ForkJoinPool;

import java.util.concurrent.RecursiveTask;

 

/**

 * Calculates a Big Sum recursively using RecursiveTask and ForkJoinPool

 * @author JoseCruz

 *

 */

class BigSUM extends RecursiveTask<Long> {

    private final long start;

    private final long end;

    

    BigSUM(long s, long e) {

        super();

        this.start = s;

        this.end = e;

    }

    

    // compute sum

    @Override

    protected Long compute() {

        

        // Is it is small enough just for one thread I will handle it!

        if(end - start < 10) {

            

            long localSoma = 0;

            for(long s = start; s <= end; s++) {

                localSoma += s;

            }

            

            // The main point of return for the recursive "loop"

            return localSoma;

        }

        

        // Lets split the effort!

        BigSUM t1 = new BigSUM(start, (end-start)/2+start);

        BigSUM t2 = new BigSUM((end-start)/2+start+1, end);

 

        // like cloning..!

        t1.fork();

        

        return t2.compute() + t1.join();

    }

    

    public static void main(String...args) {

        

        // You can get the available processores and use it to initialize the ForkJoinPool

        int processors = Runtime.getRuntime().availableProcessors();

        ForkJoinPool jfp = new ForkJoinPool(processors);

        

        // a big number...

        BigSUM t = new BigSUM(0, 10_000_000L);

        

        // calculate the sum using lots of threads

        Long result = jfp.invoke(t);

        

        System.out.println("And the sum is " + result);

        

    }

}

 

I think the code its very clear and simple, if you have questions or comments don’t hesitate to post them!

This Is a very useful tool to resolve complex problems that I really invite you to learn and use it!

No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *


six × = 42

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Bad Behavior has blocked 2220 access attempts in the last 7 days.

Hyper Smash