🕊️ 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를 직접 생성하여 작업 큐, 최대 스레드 수, 거부 정책 등을 세밀하게 조절하는 것이 더욱 안전하고 확장성 있는 선택입니다.

Java의 ExecutorService 스레드 풀 정복하기

덕토피아

Java의 ExecutorService 스레드 풀 정복하기

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2025년 3월 30일 오전 4:12

 • 

저장 23조회 2,554

댓글 0

    함께 읽은 게시물

    🚀 구글의 AI 승부수? Gemini 2.5 Pro 전면 무료화!

    h

    ... 더 보기

    ‎Gemini - chat to supercharge your ideas

    Gemini

    ‎Gemini - chat to supercharge your ideas

     • 

    저장 14 • 조회 2,818


    테크니컬 아티스트(TA, Technical Artist)의 공부법

    

    ... 더 보기

    최근 다시 강남을 중심으로 서울 아파트 값이 오르고 있다는 뉴스가 많이 보인다. 그런데 수십억하는 아파트 가격에 대해 사람들 말이 참 많다. 아니 어차피 내가 당장 혹은 근미래에 가질 수 없는 것에 대해 그게 맞다 틀리다 왈가왈부 말하는게 도대체 뭔 의미가 있는거지? 내가 가질 수 없으니 남도 갖으면 안된다는 심리인가? 가만히 보면 그런 아파트를 살 수 있는 돈 많은 사람들은 조용히 사고 팔 뿐이지 살 능력이 안되는 사람들이 뭐라뭐라 한다.


    아무리 뭐라해도 시장논리에 따라 가격이 형성되고 거래는 이루어진다. 가격에 맞춰 각각의 시장이 존재하는 것은 당연한 현상이다. 오히려 시끄럽게 할 수록 가질 수 없는 것에 대한 동경이 가격상승에 아주 극히 일부 영향을 미칠 뿐이다. 마치 연봉 1억~2억 이상 받

    ... 더 보기

     • 

    저장 7 • 조회 1,592


    🤖내 소중한 직업, AI에게 대체될까?

    "

    ... 더 보기

    나 .. 짤릴지도 ...? 🤖

    내일배움캠프

    나 .. 짤릴지도 ...? 🤖

    🎁 아미고(Ameego) 업데이트!

    ... 더 보기

    📰 대학생이 40년만에 해시테이블의 성능 향상을 이뤄냈다고

    ... 더 보기

    Optimal Bounds for Open Addressing Without Reordering

    arXiv.org

    Optimal Bounds for Open Addressing Without Reordering

     • 

    저장 40 • 조회 3,092