ForkJoinPool — ForkJoinTask 실행용 ExecutorService

ForkJoinPool — ForkJoinTask 실행용 ExecutorService

ForkJoinPoolForkJoinTask를 실행하기 위한 ExecutorService예요. work-stealing을 사용해, 대부분의 태스크가 하위 태스크를 생성하는 분할 정복 작업을 효율적으로 처리하는 풀이에요.

출처: Java API Reference

본문

개념 이해하기

ForkJoinPoolForkJoinTask를 실행하기 위한 ExecutorService이며, non-ForkJoinTask 클라이언트의 제출 진입점이자 관리·모니터링 연산을 제공해요.

public class ForkJoinPool
extends AbstractExecutorService
implements Executor, ExecutorService, AutoCloseable

다른 ExecutorService와 달리 work-stealing을 사용해요 — 풀의 모든 스레드가 풀에 제출되고/또는 다른 활성 태스크가 만든 태스크를 찾아 실행해요. 대부분의 ForkJoinTask처럼 대부분의 태스크가 하위 태스크를 생성할 때, 그리고 외부 클라이언트가 많은 작은 태스크를 제출할 때 효율적이에요. 모든 워커 스레드는 Thread.isDaemon()true로 초기화돼요.

commonPool

static commonPool()은 대부분의 애플리케이션에 적합해요. 명시적으로 지정된 풀에 제출되지 않은 모든 ForkJoinTask가 사용해요. common pool을 쓰면 비사용 기간에 스레드가 서서히 회수되고 재사용 시 복원돼 자원 사용을 줄여요.

실행 메서드 요약

호출 위치 non-fork/join 클라이언트 fork/join 계산 내부
비동기 실행 정렬 execute(ForkJoinTask) ForkJoinTask.fork()
결과 대기·획득 invoke(ForkJoinTask) ForkJoinTask.invoke()
실행 정렬 + Future 획득 submit(ForkJoinTask) ForkJoinTask.fork() (ForkJoinTask는 Future)

common pool의 생성 매개변수는 시스템 프로퍼티로 제어할 수 있어요: java.util.concurrent.ForkJoinPool.common.parallelism, ...common.threadFactory, ...common.exceptionHandler, ...common.maximumSpares (기본 256).

구현 노트: 이 구현은 최대 실행 스레드 수를 32767로 제한해요. 초과하면 IllegalArgumentException. 또한 풀이 종료됐거나 내부 자원이 고갈됐을 때만 제출된 태스크를 거부(RejectedExecutionException)해요.

생성자

public ForkJoinPool()Runtime.availableProcessors()와 같은 병렬 수준, 그 외 기본값.

  • SecurityException

public ForkJoinPool(int parallelism) — 지정된 병렬 수준.

  • IllegalArgumentException, SecurityException

public ForkJoinPool(int parallelism, ForkJoinPool.ForkJoinWorkerThreadFactory factory, Thread.UncaughtExceptionHandler handler, boolean asyncMode) — 지정된 매개변수. asyncMode가 true면 절대 join되지 않는 forked 태스크에 대해 로컬 FIFO 스케줄링 모드를 설정해요(워커 스레드가 이벤트 스타일 비동기 태스크만 처리하는 앱에 더 적합).

  • IllegalArgumentException, NullPointerException, SecurityException

public ForkJoinPool(int parallelism, ...Factory, UncaughtExceptionHandler, boolean asyncMode, int corePoolSize, int maximumPoolSize, int minimumRunnable, Predicate<? super ForkJoinPool> saturate, long keepAliveTime, TimeUnit unit) — 모든 매개변수를 지정하는 전체 생성자. (JDK 9+)

  • corePoolSize — 유지할 스레드 수(기본 병렬 수준 값), maximumPoolSize — 최대 스레드 수, minimumRunnable — join/ManagedBlocker에 의해 블로킹되지 않은 핵심 스레드의 최소 수, saturate — 최대 스레드 초과 생성 시도 시 호출되는 술어, keepAliveTime — 마지막 사용 이후 종료까지의 시간 (기본 60, TimeUnit.SECONDS)

정적·공통 메서드

public static ForkJoinPool commonPool() — common pool 인스턴스를 반환해요. 정적으로 구성되며 shutdown()/shutdownNow()에 영향받지 않아요. System.exit 시 자동 종료. 프로그램 종료 전 비동기 처리를 기다려야 하면 commonPool().awaitQuiescence 호출. (JDK 1.8+)

public static int getCommonPoolParallelism() — common pool의 목표 병렬 수준. (JDK 1.8+)

public static void managedBlock(ForkJoinPool.ManagedBlocker blocker) throws InterruptedException — 주어진 가능한 블로킹 태스크를 실행해요. ForkJoinPool에서 실행 중일 때 현재 스레드가 blocker.block()에 블로킹되는 동안 충분한 병렬성을 위해 스페어 스레드를 활성화할 수 있어요. blocker.isReleasable()/blocker.block()true가 될 때까지 반복해요.

실행 메서드

public <T> T invoke(ForkJoinTask<T> task) — 태스크를 수행하고 완료 시 결과를 반환해요. 비검사 예외/오류는 재던져져요.

  • NullPointerException, RejectedExecutionException

public void execute(ForkJoinTask<?> task) — (비동기) 실행을 정렬해요.

  • NullPointerException, RejectedExecutionException

public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) — 실행을 제출하고 태스크를 반환해요. 대기 중 결과는 태스크 자체가 Future예요.

public <T> ForkJoinTask<T> externalSubmit(ForkJoinTask<T> task) — non-ForkJoinTask 클라이언트처럼 제출해요. 풀의 스레드에서 호출해도 스케줄링 큐에 추가돼요. (JDK 20+)

public <T> ForkJoinTask<T> lazySubmit(ForkJoinTask<T> task) — 활성 스레드가 없어도 결국 실행됨을 보장하지 않고 제출해요. 경합·오버헤드를 줄일 수 있어요. (JDK 19+)

submit(Callable), submit(Runnable, result), submit(Runnable), invokeAll(Collection)도 제공돼요.

관리·상태

public int setParallelism(int size) — 병렬 수준을 변경하고 이전 값을 반환해요. (JDK 19+). IllegalArgumentException, UnsupportedOperationException (commonPool이 프로퍼티로 설정된 경우), SecurityException.

public ForkJoinPool.ForkJoinWorkerThreadFactory getFactory(), public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() — 팩토리/핸들러 반환.

public int getParallelism() — 목표 병렬 수준.

public int getPoolSize() — 시작됐지만 종료되지 않은 워커 스레드 수.

public boolean getAsyncMode() — async 모드 여부.

public int getRunningThreadCount() — join 태스크 대기나 다른 관리 동기화에 블로킹되지 않은 워커 수 추정치.

public int getActiveThreadCount() — 현재 훔치거나 실행 중인 스레드 수 추정치.

public boolean isQuiescent() — 모든 워커가 유휴면 true. 보수적.

public long getStealCount() — 제출자 아닌 다른 스레드가 실행한 완료 태스크 수 추정치.

public long getQueuedTaskCount() / public int getQueuedSubmissionCount() / public boolean hasQueuedSubmissions() — 큐된 태스크/제출 수.

종료

public void shutdown() — 질서 있는 정리. commonPool()이면 실행 상태에 영향 없음. SecurityException.

public List<Runnable> shutdownNow() — 모든 태스크 취소·중지 시도. 항상 빈 목록을 반환해요(태스크 의존성 때문에 기존·미실행 태스크를 모두 취소하므로). commonPool()이면 영향 없음.

public boolean isTerminated(), public boolean isTerminating(), public boolean isShutdown() — 상태 질의.

public boolean awaitTermination(long timeout, TimeUnit unit) — 종료 대기. common pool엔 awaitQuiescence와 동등하되 항상 false 반환.

public boolean awaitQuiescence(long timeout, TimeUnit unit) — 풀이 quiescent되거나 타임아웃까지 대기하거나 태스크 수행을 지원.

public void close()commonPool()이 아니면 질서 있는 종료 후 완료·종료까지 대기. (JDK 19+)

public String toString() — 풀 상태(실행 상태, 병렬 수준, 워커·태스크 수)를 식별하는 문자열.

더 알아보기 (Learn more)