Java의 ExecutorService 스레드 풀 정복하기
덕토피아
이번 글에서는 Executors가 제공하는 대표적인 스레드 풀 4종류를 살펴보고, 각각의 사용 시나리오와 주의할 점을 예제 중심으로 정리해보겠습니다.
newFixedThreadPool(int nThreads)
이 메서드는 정해진 개수만큼의 스레드를 미리 생성하고, 그 스레드들이 재사용되며 작업을 처리합니다. 더 많은 작업이 들어오면 내부 큐에 쌓이고, 기존 스레드들이 작업을 처리하면 순차적으로 소비됩니다.
ExecutorService executor = Executors.newFixedThreadPool(4);
✅ 사용 시점
처리할 작업량은 많지만, 동시에 처리해야 하는 작업 수를 제한하고 싶은 경우
CPU 자원을 고르게 사용하며, 안정적인 처리량을 원하는 경우
🧪 예시
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
Thread.sleep(1000); // 모의 작업
});
}
⚠️ 주의
과도하게 큰 작업 큐가 쌓일 수 있음 → 메모리 사용량 증가
스레드 수는 CPU 코어 수나 애플리케이션 특성에 맞게 설정해야 함
newCachedThreadPool()
이 스레드 풀은 요청이 많으면 새로운 스레드를 계속 생성하고, 특정 기간 동안 사용되지 않으면 제거합니다. 캐시된 스레드를 재사용하므로 빠르고 유연합니다.
ExecutorService executor = Executors.newCachedThreadPool();
✅ 사용 시점
작업이 짧고 빠르게 끝나는 I/O 중심의 작업일 때
짧은 burst가 자주 발생하는 상황에서 유용
🧪 예시
for (int i = 0; i < 100; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
});
}
⚠️ 주의
요청이 많을 경우 스레드가 무제한으로 늘어나 과부하가 될 수 있음
→ 실제 운영에서는 ThreadPoolExecutor로 커스텀 제어 필요
newSingleThreadExecutor()
항상 단 하나의 스레드만 사용하여 작업을 처리합니다. 작업은 FIFO 순서로 실행되며, 순서가 중요한 로직에 적합합니다.
ExecutorService executor = Executors.newSingleThreadExecutor();
✅ 사용 시점
작업 순서가 중요할 때
하나의 리소스(DB, 파일 등)에 대해 직렬화된 접근이 필요할 때
🧪 예시
for (int i = 0; i < 5; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Processing task " + taskId);
Thread.sleep(500);
});
}
⚠️ 주의
하나의 스레드에 의존하기 때문에 처리량은 낮음
스레드가 죽으면 새로운 스레드로 대체되므로 중단되지는 않음
newScheduledThreadPoool(int corePoolSize)
지연 실행(delay)이나 주기적인 작업(interval) 실행에 특화된 스레드 풀입니다. ScheduledExecutorService를 반환하며, Java의 타이머 역할도 수행할 수 있습니다.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
✅ 사용 시점
주기적인 백업 작업, 모니터링, 알림 전송 등
특정 시간 후 작업을 실행하고 싶을 때
🧪 예시
scheduler.scheduleAtFixedRate(() -> {
System.out.println("Heartbeat sent by " + Thread.currentThread().getName());
}, 1, 5, TimeUnit.SECONDS); // 1초 후 시작, 5초마다 반복
⚠️ 주의
작업이 너무 오래 걸리면 다음 주기 작업이 지연될 수 있음
→ 처리 시간이 일정하지 않다면 scheduleWithFixedDelay()를 고려
🧠 마무리
Java에서 Executors 팩토리 메서드는 다양한 형태의 스레드 풀을 간단히 생성할 수 있게 도와줍니다. 하지만, 운영 환경에서는 ThreadPoolExecutor를 직접 생성하여 작업 큐, 최대 스레드 수, 거부 정책 등을 세밀하게 조절하는 것이 더욱 안전하고 확장성 있는 선택입니다.
다음 내용이 궁금하다면?
이미 회원이신가요?
2025년 3월 30일 오전 4:12
Different types of ExecutorService in Java are suitable for various scenarios. Especially in game servers, like in bubble shooter where many short tasks are handled, choosing the right pool boosts performance. Proper configuration optimizes resource management. https://bubbleshooterfun.de
데
... 더 보기M
... 더 보기이
... 더 보기솔
... 더 보기