ForkJoinPool
java 7부터 사용가능한 Java Concurrency Framework
분할 정복(Divide and Conquer) 알고리즘과 유사한 구조
동일한 작업을 여러 개의 Sub Task로 분리(Fork)하여 각각 처리하고, 이를 최종적으로 합쳐서(Join) 결과를 만들어내는 방식 -> 대규모 작업을 빠르게 처리하는 데 도움
스레드풀의 큐(inbound queue)에 작업이 할당되면 pool 내의 스레드들이 해당 작업을 가져가서 수행한다.
각 스레드들은 다시 본인의 작업 큐(work queue)를 가진다.
각 스레드들의 작업 큐는 deque 자료구조를 가진다
(작업 스레드는 한쪽에서 꺼내 쓰고, 다른 스레드가 작업을 stealing 할 때 다른 한쪽을 사용)
작업 스틸링(Work Stealing): 작업자 스레드가 일할 작업이 없으면 다른 스레드의 큐에서 작업을 가져옵니다.
이를 통해 스레드 간의 작업 부하를 균형잡히게 유지하고, 모든 스레드가 계속 작업을 수행할 수 있도록 합니다.
주의점
작업 분할 및 작업 스틸링에는 일정한 오버헤드가 있다.
단순 threadPoolExecutor를 사용하는 경우가 더 빠를 수 있다.
ParellelStream
parellelStream 내부적으로 ForkJoinPool을 사용
보통은 default로 commonPool을 이용
parellelStream을 수행할 thread의 개수를 정해주고 싶은 경우 아래와 같이 사용 가능
다만, 사용 완료 후 shutdown 호출해야 메모리 leak 방지 가능
ForkJoinPool forkJoinPool = new ForkJoinPool(6);
forkJoinPool.submit(() -> {
integerList.parallelStream().forEach((integer) -> { ...})
}
forkJoinPool.shutdown();