Java Fork/Join Framework examples
What is Fork/Join?
Read this Java Fork/Join paper by Doug Lea
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.
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
Both are same, just
RecursiveTask
returns a value, while RecursiveAction return nothing, void.
Download Source Code
$ git clone https://github.com/mkyong/java-concurrency.git
it is really good site
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 ?
Why is it faster to solve fibonacci with classic loop on single thread than using fork join multiple threads ? Great article by the way 🙂
it’s not, but in this example it is solved with recursion which is slower than iterative in this case