Main Tutorials

Java Fork/Join Framework examples

What is Fork/Join?
Read this Java Fork/Join paper by Doug Lea

The fork/join framework is available since Java 7, to make it easier to write parallel programs. We can implement the fork/join framework by extending either RecursiveTask or RecursiveAction

1. Fork/Join – RecursiveTask

A fork join example to sum all the numbers from a range.

ForkJoinAdd.java

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

public class ForkJoinAdd extends RecursiveTask<Long> {

    private final long[] numbers;
    private final int start;
    private final int end;
    public static final long threshold = 10_000;

    public ForkJoinAdd(long[] numbers) {
        this(numbers, 0, numbers.length);
    }

    private ForkJoinAdd(long[] numbers, int start, int end) {
        this.numbers = numbers;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {

        int length = end - start;
        if (length <= threshold) {
            return add();
        }

        ForkJoinAdd firstTask = new ForkJoinAdd(numbers, start, start + length / 2);
        firstTask.fork(); //start asynchronously

        ForkJoinAdd secondTask = new ForkJoinAdd(numbers, start + length / 2, end);

        Long secondTaskResult = secondTask.compute();
        Long firstTaskResult = firstTask.join();

        return firstTaskResult + secondTaskResult;

    }

    private long add() {
        long result = 0;
        for (int i = start; i < end; i++) {
            result += numbers[i];
        }
        return result;
    }

    public static long startForkJoinSum(long n) {
        long[] numbers = LongStream.rangeClosed(1, n).toArray();
        ForkJoinTask<Long> task = new ForkJoinAdd(numbers);
        return new ForkJoinPool().invoke(task);
    }

}

Run it. Sum all the numbers from 1 to 1 million.

Main.java

package com.mkyong.concurrency.forkjoin;

public class Main {

    public static void main(String[] args) {

        System.out.println(ForkJoinAdd.startForkJoinSum(1_000_000));
		
    }

}

Output


500000500000

2. Fork/Join – RecursiveAction

A fork join example to find the Fibonacci number by using recursive loop.

Note
This method is used for Fork/Join demo only, recursive loop is slow. Try this Java Fibonacci examples to find the Fibonacci number faster.
ForkJoinFibonacci.java

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;

public class ForkJoinFibonacci extends RecursiveAction {

    private static final long threshold = 10;
    private volatile long number;

    public ForkJoinFibonacci(long number) {
        this.number = number;
    }

    public long getNumber() {
        return number;
    }

    @Override
    protected void compute() {
        long n = number;
        if (n <= threshold) {
            number = fib(n);
        } else {
            ForkJoinFibonacci f1 = new ForkJoinFibonacci(n - 1);
            ForkJoinFibonacci f2 = new ForkJoinFibonacci(n - 2);
            ForkJoinTask.invokeAll(f1, f2);
            number = f1.number + f2.number;
        }
    }

    private static long fib(long n) {
        if (n <= 1) return n;
        else return fib(n - 1) + fib(n - 2);
    }

}

Run it, find the 50th Fibonacci number.

Main.java

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinPool;

public class Main {

    public static void main(String[] args) {

        ForkJoinFibonacci task = new ForkJoinFibonacci(50);
        new ForkJoinPool().invoke(task);

        System.out.println(task.getNumber());

    }

}

Output


12586269025
Difference between RecursiveTask and RecursiveAction?
Both are same, just RecursiveTask returns a value, while RecursiveAction return nothing, void.

Download Source Code

References

  1. Oracle – Fork/Join
  2. A Java Fork-Join Calamity
  3. Doug Lea – A Java Fork/Join Framework
  4. Wikipedia – Fibonacci number
  5. Java Fibonacci examples
  6. RecursiveTask JavaDoc
  7. RecursiveAction JavaDoc

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Ruhul Amin
5 years ago

it is really good site

Atif
4 years ago

hi mkyong, firstly thank you for explaining the concept so well!!!!
I did notice that you marked the number as volatile.
I did not feel it was needed .. what do you say on this ?

Jaros?aw
4 years ago

Why is it faster to solve fibonacci with classic loop on single thread than using fork join multiple threads ? Great article by the way 🙂

uri
4 years ago
Reply to  Jaros?aw

it’s not, but in this example it is solved with recursion which is slower than iterative in this case