ExecutorService는 Executor를 확장한 인터페이스로, 작업 실행뿐만 아니라 라이프사이클 관리와 결과 추적까지 제공한다.
public interface ExecutorService extends Executor {
// 라이프사이클 관리
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit);
// 결과를 반환하는 작업 제출
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
// 여러 작업 동시 실행
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks);
<T> T invokeAny(Collection<? extends Callable<T>> tasks);
}
💡 작업제출(Task)메서드로, Executor에서 상속받은
void execute(Runnable command)도 있음. 이 친구는 라이프사이클 통제가 안된다. 일 시키면 다음부턴 추적이 안됨.
// CPU 집약적 작업 (계산, 이미지 처리 등)
ExecutorService cpu = Executors.newWorkStealingPool();
// I/O 집약적 작업 (HTTP, DB, 파일 등) - Java 21+
ExecutorService io = Executors.newVirtualThreadPerTaskExecutor();
// I/O 집약적 작업 - Java 21 미만
ExecutorService io = Executors.newCachedThreadPool();
// 순차 실행이 필요한 작업
ExecutorService sequential = Executors.newSingleThreadExecutor();
// 주기적/지연 실행
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(5);
// 일반적인 작업 (균형)
ExecutorService general = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors() * 2
);
💡 VirtualThreadPerTaskExecutor는 이름에 TaskExecutor가 있지만, 스프링 패키지가 아님. JDK21소속이다.