fork() : 해당 작업을 쓰레드 풀의 작업 큐에 넣는다. - 비동기 메서드
join() : 해당 작업의 수행이 끝날 때까지 기다렸다가, 수행이 끝나면 그 결과를 반환한다. - 동기 메서드
병렬화할 수 있는 작업을 재귀적으로 작은 작업으로 분할한 다음에 서브태스크 각각의 결과를 합쳐서 전체 결과를 만들도록 설계되었다.
포크/조인 프레임 워크에서는 서브태스크를 스레드 풀(ForkJoinPool)의 작업자 스레드에 분산 할당하는 ExcutorService 인터페이스를 구현한다.
RecursiveTask, RecursiveAction
RecursiveTask
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;
public class ForkJoin extends RecursiveTask<Integer> {
private final List<Integer> numbers;
public ForkJoin(List<Integer> numbers) {
this.numbers = numbers;
}
@Override
protected Integer compute() {
if (numbers.size() <= 10) { // 배열의 크기가 10과 같거나 작으면 배열을 전부 더한 값을 반환한다.
return numbers.stream().mapToInt(Integer::intValue).sum();
}
List<Integer> leftPart = numbers.subList(0, numbers.size() / 2);
List<Integer> rightPart = numbers.subList(numbers.size() / 2, numbers.size());
ForkJoin leftTask = new ForkJoin(leftPart);
ForkJoin rightTask = new ForkJoin(rightPart);
// Task를 배열 사이즈의 절반을 기준으로 2개로 나눈다.
leftTask.fork(); // ForkJoinPool의 다른 스레드로 새로 생성한 태스크를 비동기로 실행
return rightTask.compute() + leftTask.join();
}