ForkJoinTask — ForkJoinPool에서 실행되는 태스크
ForkJoinTask — ForkJoinPool에서 실행되는 태스크
ForkJoinTask<V>는 ForkJoinPool 내에서 실행되는 태스크를 위한 추상 기본 클래스예요. 일반 스레드보다 훨씬 가벼운 스레드 유사 엔티티이며, Future의 가벼운 형태예요.
본문
개념 이해하기
ForkJoinTask는 ForkJoinPool 내에서 실행되는 태스크를 위한 추상 기본 클래스예요. 일반 스레드보다 훨씬 가벼워서, 많은 수의 태스크·하위 태스크를 소수의 실제 스레드가 호스팅할 수 있어요.
public abstract class ForkJoinTask<V>
extends Object
implements Future<V>, Serializable
- "메인" ForkJoinTask는 명시적으로
ForkJoinPool에 제출되거나,ForkJoinPool.commonPool()에서fork()/invoke()로 시작돼요. - 주요 조정 메커니즘은
fork()(비동기 실행 정렬)와join()(결과가 계산될 때까지 진행하지 않음)이에요. - 계산은 이상적으로
synchronized블록을 피하고, 검사 예외(IOException 등)를 던질 수 없도록 느슨하게 강제돼요. 비검사 예외는 join하려는 호출자에게 재던져져요. join()과 그 변형은 완료 의존성이 비순환적(DAG) 일 때만 적절해요. 그 외엔 데드락이 생길 수 있어요.- 태스크는 상대적으로 작은 계산을 수행해야 해요 — 대략 100~10000 기본 계산 단계. 태스크가 너무 크면 병렬성이 처리량을 개선하지 못하고, 너무 작으면 오버헤드가 지배해요.
- 직접 서브클래스화하지 않고 보통
RecursiveAction(결과 없음),RecursiveTask(결과 있음),CountedCompleter(완료가 다른 액션 촉발)를 서브클래스화해요.
핵심 실행 메서드
public final ForkJoinTask<V> fork() — 현재 태스크가 실행 중인 풀(해당 시) 또는 commonPool()에서 비동기 실행을 정렬해요. 완료 전 tasks를 여러 번 fork하는 건 사용 오류예요. 반환 this.
public final V join() — 완료 시 계산 결과를 반환해요. get()과 달리 비정상 완료가 ExecutionException이 아니라 RuntimeException/Error를 일으켜요.
public final V invoke() — 이 태스크 수행을 시작하고 필요시 완료를 기다린 뒤 결과를 반환해요.
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) / invokeAll(ForkJoinTask<?>... tasks) / public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) — 주어진 태스크를 fork하고 각각 isDone이 될 때까지(또는 예외 시 재던짐) 반환해요.
완료·상태
public boolean cancel(boolean mayInterruptIfRunning) — 실행 취소를 시도해요. 기본 구현에서 mayInterruptIfRunning은 효과가 없어요(인터럽트가 취소를 제어하지 않으므로). 성공 후 isCancelled()·isDone()·cancel은 true, join()은 CancellationException.
public final boolean isDone(), public final boolean isCancelled(), public final boolean isCompletedNormally(), public final boolean isCompletedAbnormally() — 상태 질의.
public final Throwable getException() — 기본 계산이 던진 예외, 취소면 CancellationException, 없거나 미완료면 null.
public void completeExceptionally(Throwable ex) — 비정상 완료. join 및 관련 연산이 예외를 던지게 해요.
public void complete(V value) — 정상 완료시키고 결과 값을 반환하게 해요.
public final void quietlyComplete() — 값 설정 없이 정상 완료. (JDK 1.8+)
public final V get() / public final V get(long timeout, TimeUnit unit) — Future 방식의 인터럽트 가능/타임아웃 대기 결과 조회.
public final void quietlyJoin(), public final void quietlyInvoke() — 결과·예외를 추출하지 않고 join/invoke.
public final boolean quietlyJoin(long timeout, TimeUnit unit) — 타임아웃까지 완료됐으면 true, 인터럽트 가능. (JDK 19+)
public final boolean quietlyJoinUninterruptibly(long timeout, TimeUnit unit) — 인터럽트 불가 변형. (JDK 19+)
public static void helpQuiesce() — 호스팅 풀이 quiescent될 때까지 가능한 태스크를 실행해요.
public void reinitialize() — 내부 북키핑을 재설정해 후속 fork를 허용해요.
팩토리·헬퍼
public static ForkJoinPool getPool() — 현재 스레드를 호스팅하는 풀 또는 null(없으면).
public static boolean inForkJoinPool() — 현재 스레드가 ForkJoinPool 계산으로 실행 중이면 true.
public boolean tryUnfork() — 이 태스크의 실행을 예약 해제(unschedule)하려 시도해요.
public static int getQueuedTaskCount() / public static int getSurplusQueuedTaskCount() — 로컬 큐 추정/잉여.
public abstract V getRawResult() / protected abstract void setRawResult(V value) / protected abstract boolean exec() — 서브클래스가 구현해야 하는 기본 메서드.
태그
public final short getForkJoinTaskTag() / public final short setForkJoinTaskTag(short newValue) / public final boolean compareAndSetForkJoinTaskTag(short expect, short update) — 태스크에 short 태그를 지정해 그래프 순회의 방문 표시(compareAndSetForkJoinTaskTag((short)0, (short)1)) 등에 쓰일 수 있어요. (JDK 1.8+)
adapt
public static ForkJoinTask<?> adapt(Runnable runnable) — run을 액션으로 수행하고 join() 시 null 반환하는 태스크를 반환해요.
public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) — join() 시 주어진 결과를 반환.
public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) — call을 액션으로 수행하고 결과를 반환, 검사 예외는 RuntimeException으로 변환.
public static <T> ForkJoinTask<T> adaptInterruptible(Callable<? extends T> callable) — cancel(mayInterruptIfRunning=true)이 태스크를 수행하는 스레드를 인터럽트하려 시도하는 변형. (JDK 19+)