[CS] Thread Pool 이란?

Hyunjun Kim·2025년 7월 18일
0

Computer_Science

목록 보기
11/19

스레드 풀(Thread Pool)이란?

1. 스레드와 풀의 개념

  • 스레드(Thread): 프로그램 내에서 실제 작업을 수행하는 실행 흐름의 단위이다.
  • 풀(Pool): 필요한 객체를 매번 새로 생성하지 않고, 미리 생성해 둔 객체를 재사용하는 집합이다.

따라서, 스레드 풀(Thread Pool)은 미리 정해진 개수만큼 스레드를 만들어 두고, 작업이 들어오면 이들 중 사용 가능한 스레드를 할당하여 작업을 처리하는 방식이다.
작업이 끝난 스레드는 바로 제거되지 않고 다시 풀로 돌아가서 다음 작업에 재사용된다. 이렇게 하면 반복적으로 스레드를 생성하고 소멸하는 비용을 줄일 수 있다.


2. 스레드 풀이 필요한 이유

서버 프로그램(예: 웹 서버, 데이터베이스 서버 등)은 수많은 클라이언트 요청을 처리해야 한다.
만약 요청마다 새로운 스레드를 생성하고, 작업이 끝나면 스레드를 버리는 식이라면 다음과 같은 문제점이 발생한다.

  • 스레드 생성 비용 증가: 스레드 생성과 소멸은 CPU와 메모리 자원을 많이 소모하는 작업이다.
  • 컨텍스트 스위칭 비용 증가: 너무 많은 스레드가 존재하면 CPU가 여러 스레드 사이를 자주 전환해야 해서 오버헤드가 커진다.
  • 메모리 고갈 위험: 무한정 스레드가 생성되면 서버의 메모리가 부족해져서 시스템 전체가 멈출 수 있다.

이런 문제를 해결하기 위해 스레드 풀을 사용하면, 미리 일정 개수의 스레드를 만들어 놓고 재활용하여 작업 처리 속도를 높이고 자원 낭비를 줄일 수 있다.


3. 스레드 풀의 동작 원리

  1. 서버가 시작할 때 미리 정해진 수만큼 스레드를 생성해 둔다.
  2. 클라이언트 요청과 같은 작업(Task)이 작업 큐(Queue)에 들어온다.
  3. 작업 큐에서 작업을 꺼내 사용 가능한 스레드에 할당하여 실행한다.
  4. 작업이 끝나면 스레드는 제거되지 않고 다시 대기 상태로 돌아가서 다음 작업을 기다린다.

4. 스레드 풀의 장점과 단점

장점

  • 성능 향상: 스레드 생성과 종료 비용을 절감해 처리 속도가 빨라진다.
  • 응답성 개선: 이미 생성된 스레드를 재사용하기 때문에 즉각적으로 작업을 시작할 수 있다.
  • 자원 제한 가능: 스레드 개수를 제한함으로써, 급격한 요청 폭주에도 서버가 안정적으로 동작하도록 제어할 수 있다.

단점

  • 메모리 사용: 미리 많은 스레드를 생성하면 메모리 낭비가 발생할 수 있다.
  • 적절한 크기 설정의 어려움: 너무 적거나 너무 많은 스레드 수는 모두 성능 저하를 유발할 수 있어, 적절한 크기를 찾는 것이 중요하다.

5. Java에서 스레드 풀 사용하기

Java에서는 java.util.concurrent 패키지 내 Executors 클래스와 ExecutorService 인터페이스를 사용하여 스레드 풀을 쉽게 만들고 관리할 수 있다.

5.1 주요 스레드 풀 종류

  • FixedThreadPool (고정 크기 스레드 풀)
    미리 정해진 수의 스레드를 생성하여 고정된 개수만큼만 작업을 병렬 처리한다.
    요청이 많으면 작업은 큐에 쌓이고, 스레드가 하나 끝나면 큐에서 작업을 꺼내 처리한다.
ExecutorService executorService = Executors.newFixedThreadPool(10);  
  • CachedThreadPool (가변 크기 스레드 풀)
    필요에 따라 스레드를 동적으로 생성하고, 유휴 상태인 스레드는 일정 시간 후 종료한다.
    작업량이 많을 때 빠르게 확장되지만 스레드가 폭발적으로 늘어날 위험도 있다.
ExecutorService executorService = Executors.newCachedThreadPool();  
  • ThreadPoolExecutor (커스텀 설정 가능)
    코어 스레드 수, 최대 스레드 수, 대기 큐 등 다양한 설정을 직접 지정할 수 있다.
ExecutorService myThreadPool = new ThreadPoolExecutor(  
    5, // 코어 스레드 수  
    50, // 최대 스레드 수  
    60, // 유휴 스레드 유지 시간  
    TimeUnit.SECONDS,   
    new LinkedBlockingQueue<>() // 작업 큐  
);  

5.2 스레드 풀 종료

  • shutdown() : 현재 실행 중인 작업과 대기 중인 작업이 모두 끝난 뒤 스레드 풀을 종료한다.
  • shutdownNow() : 실행 중인 작업을 즉시 중단시키고, 대기 중인 작업 목록을 반환한다.
  • awaitTermination(timeout, unit) : shutdown() 호출 후, 지정한 시간 내에 모든 작업이 종료되었는지 기다린다.
executorService.shutdown();  
if (executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
    System.out.println("스레드 풀 정상 종료");  
} else {  
    System.out.println("시간 초과로 강제 종료 필요");  
}  

6. 적절한 스레드 풀 크기 설정 방법

  • CPU-bound 작업: CPU 코어 수와 같거나 약간 더 많은 수가 적당하다.
  • IO-bound 작업: 코어 수의 1.5배 ~ 3배 정도까지 늘릴 수 있다. IO 대기 시간 동안 CPU가 다른 작업을 처리할 수 있기 때문이다.

정리

스레드 풀은 서버나 멀티태스킹 환경에서 효율적으로 자원을 관리하며 안정적인 성능을 제공하는 필수 기술이다.
스레드의 생성과 소멸에 따른 비용을 줄이고, 작업을 빠르게 처리하며, 시스템 부하를 조절할 수 있다는 점에서 매우 중요하다.

profile
Data Analytics Engineer 가 되

0개의 댓글