따라서, 스레드 풀(Thread Pool)은 미리 정해진 개수만큼 스레드를 만들어 두고, 작업이 들어오면 이들 중 사용 가능한 스레드를 할당하여 작업을 처리하는 방식이다.
작업이 끝난 스레드는 바로 제거되지 않고 다시 풀로 돌아가서 다음 작업에 재사용된다. 이렇게 하면 반복적으로 스레드를 생성하고 소멸하는 비용을 줄일 수 있다.
서버 프로그램(예: 웹 서버, 데이터베이스 서버 등)은 수많은 클라이언트 요청을 처리해야 한다.
만약 요청마다 새로운 스레드를 생성하고, 작업이 끝나면 스레드를 버리는 식이라면 다음과 같은 문제점이 발생한다.
이런 문제를 해결하기 위해 스레드 풀을 사용하면, 미리 일정 개수의 스레드를 만들어 놓고 재활용하여 작업 처리 속도를 높이고 자원 낭비를 줄일 수 있다.
Java에서는 java.util.concurrent
패키지 내 Executors
클래스와 ExecutorService
인터페이스를 사용하여 스레드 풀을 쉽게 만들고 관리할 수 있다.
ExecutorService executorService = Executors.newFixedThreadPool(10);
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorService myThreadPool = new ThreadPoolExecutor(
5, // 코어 스레드 수
50, // 최대 스레드 수
60, // 유휴 스레드 유지 시간
TimeUnit.SECONDS,
new LinkedBlockingQueue<>() // 작업 큐
);
shutdown()
: 현재 실행 중인 작업과 대기 중인 작업이 모두 끝난 뒤 스레드 풀을 종료한다. shutdownNow()
: 실행 중인 작업을 즉시 중단시키고, 대기 중인 작업 목록을 반환한다. awaitTermination(timeout, unit)
: shutdown()
호출 후, 지정한 시간 내에 모든 작업이 종료되었는지 기다린다. executorService.shutdown();
if (executorService.awaitTermination(60, TimeUnit.SECONDS)) {
System.out.println("스레드 풀 정상 종료");
} else {
System.out.println("시간 초과로 강제 종료 필요");
}
스레드 풀은 서버나 멀티태스킹 환경에서 효율적으로 자원을 관리하며 안정적인 성능을 제공하는 필수 기술이다.
스레드의 생성과 소멸에 따른 비용을 줄이고, 작업을 빠르게 처리하며, 시스템 부하를 조절할 수 있다는 점에서 매우 중요하다.