fork & join 프레임웍
fork & join 프레임웍은 하나의 작업을 작은 단위로 나눠서 여러 스레드가 동시에 처리하는것을 쉽게 만들어준다.
RecursiveAction과 RecursiveTask 두 클래스 중에서 하나를 상속받아 구현한다.
RecursiveAction 반환값이 없는 작업할때
RecursiveTask 반환값이 있는 작업할때
Fork-Join 프레임워크는 작업을 병렬로 처리함으로써 성능을 향상시키고, 멀티코어 프로세서에서의 활용도를 높인다.
Fork-Join 프레임워크의 핵심 구성 요소는 다음과 같다.
1. ForkJoinPool: Fork-Join 작업을 실행하는 스레드 풀
2. ForkJoinTask: Fork-Join 프레임워크의 작업을 나타내는 추상 클래스
3. RecursiveTask: 반환 값을 가지는 작업을 나타내는 클래스로, `ForkJoinTask`를 상속
4. RecursiveAction: 반환 값이 없는 작업을 나타내는 클래스로, `ForkJoinTask`를 상속
예시로 배열의 요소들의 합을 병렬로 계산하는 예제를보자.
`SumTask` 클래스가 배열의 합을 계산하는 작업을 수행한다.
만약 배열의 길이가 임계값(`THRESHOLD`) 이하라면 작업을 직접 처리하고, 그렇지 않으면 배열을 두 개의 하위 배열로 분할하여 병렬로 처리한다.
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumTask extends RecursiveTask<Integer> {
private static final int THRESHOLD = 10;
private int[] array;
private int start;
private int end;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= THRESHOLD) {
int 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();
int rightResult = rightTask.compute();
int leftResult = leftTask.join();
return leftResult + rightResult;
}
}
}
public class ForkJoinExample {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ForkJoinPool pool = new ForkJoinPool();
SumTask task = new SumTask(array, 0, array.length);
int result = pool.invoke(task);
System.out.println("Sum: " + result);
}
}