The Fork/Join Framework, introduced in Java 7 as part of the java.util.concurrent
package, is designed to take advantage of multiple processors available in modern systems. It provides a powerful tool for parallel programming, allowing tasks to be recursively divided into smaller tasks and executed concurrently.
What is the Fork/Join Framework?
The Fork/Join Framework follows the divide-and-conquer principle. It splits a large task into smaller subtasks (fork), executes them in parallel, and then combines their results (join).
This framework is ideal for problems that can be recursively divided into independent subtasks, such as processing large datasets, performing mathematical computations, or rendering graphics.
- ForkJoinPool: The core of the Fork/Join Framework, managing the worker threads.
- ForkJoinTask: The abstract class representing a task. Subclasses include:
RecursiveAction
: For tasks that do not return a result.RecursiveTask
: For tasks that return a result.
Syntax of the Fork/Join Framework
1. Define the Task
Extend RecursiveTask<V>
if the task returns a value. Extend RecursiveAction
if the task does not return a value.
import java.util.concurrent.RecursiveTask;
public class MyTask extends RecursiveTask<Integer> {
private int start, end;
public MyTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if ((end - start) <= THRESHOLD) {
return computeDirectly();
} else {
int mid = (start + end) / 2;
MyTask leftTask = new MyTask(start, mid);
MyTask rightTask = new MyTask(mid, end);
leftTask.fork();
return rightTask.compute() + leftTask.join();
}
}
private Integer computeDirectly() {
int result = 0;
for (int i = start; i < end; i++) {
result += i;
}
return result;
}
}
2. Execute the Task
import java.util.concurrent.ForkJoinPool;
public class ForkJoinExample {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
MyTask task = new MyTask(1, 1000);
int result = pool.invoke(task);
System.out.println("Result: " + result);
}
}
Example: Summing an Array with Fork/Join
Here is a complete example that demonstrates how to sum an array using the Fork/Join Framework:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumTask extends RecursiveTask<Long> {
private static final int THRESHOLD = 10;
private int[] array;
private int start, end;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if ((end - start) <= THRESHOLD) {
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
int mid = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, mid);
SumTask rightTask = new SumTask(array, mid, end);
leftTask.fork();
long rightResult = rightTask.compute();
long leftResult = leftTask.join();
return leftResult + rightResult;
}
}
}
public class ForkJoinArraySum {
public static void main(String[] args) {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
ForkJoinPool pool = new ForkJoinPool();
SumTask task = new SumTask(array, 0, array.length);
long result = pool.invoke(task);
System.out.println("Sum: " + result);
}
}
Key Points to Remember
- Threshold: Set an appropriate threshold to balance task splitting and computation.
- Work Stealing: The Fork/Join Framework uses a work-stealing algorithm to balance workloads across threads.
- RecursiveTask vs RecursiveAction: Use
RecursiveTask
for tasks that return results andRecursiveAction
for void tasks. - ForkJoinPool: Manages task execution. By default, it matches the number of available processors.
When to Use the Fork/Join Framework
- Best for CPU-intensive tasks.
- Suitable for problems that can be divided into smaller independent tasks.
- Not ideal for I/O-bound tasks as it relies on keeping the CPU busy.
The Fork/Join Framework provides a robust mechanism for parallel programming in Java. By mastering it, you can harness the power of modern multi-core processors and significantly improve application efficiency.
0 Comments