본문 바로가기

명사 美 비격식 (무리 중에서) 아주 뛰어난[눈에 띄는] 사람[것]

JAVA

하나의 작업을 작은 단위로 나눠서 여러 스레드가 동시에 처리한다, fork & join 프레임웍

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);
    }
}