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

mkyong

Founder of Mkyong.com, passionate Java and open-source technologies. If you enjoy my tutorials, consider making a donation to these charities.

4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Ruhul Amin
7 years ago

it is really good site

Atif
6 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
6 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
6 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