ThreadPoolExecutor
는 어떻게 동작하나요?
쓰레드를 미리 생성하고, 작업 요청이 발생할 때 마다 미리 생성된 쓰레드로 해당 작업을 처리하는 방식.
서버가 모든 요청에 대해 스레드를 매번 생성하게 하면 메모리 초과로 서버가 다운될 수 있기 때문.
일정 수의 스레드를 미리 생성해놓고 할당하는 방식으로 동시 처리를 진행한다.
여러 풀링된 스레드 중 하나를 사용하여 제출된 각 작업을 실행하는 객체.
ThreadPoolExecutor
객체를 생성하려고 하면 다음과 같은 생성자가 존재한다.
여기서 공통으로 가지는 파라미터에 대해 알아보자.
corePoolSize
maximumPoolSize
keepAliveTime
unit
workQueue
corePoolSize = 1
maximumPoolSize = 5
keepAliveTime = 3
unit = SECONDS
workQueue = 7 (최대 7개의 쓰레드가 보관이 가능하다.)
해당 설정의 스레드 풀이 있다고 하자.
10개의 요청이 동시에 들어와 10개의 스레드가 필요하다면?
1. corePoolSize 만큼 스레드 실행.
2. workQueue 사이즈만큼 큐에 스레드 보관
3. maximumPoolSize가 5개이므로 현재 1개만 실행중이니 4개의 스레드 생성이 가능함.
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;
public class WebServer {
public static void main(String args[]) throws Exception {
//해당 큐는 7개까지 쓰레드 저장이 가능하다.
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(7);
ThreadPoolExecutor executorService =
new ThreadPoolExecutor(1,5,3, SECONDS, queue);
for (int i = 0; i < 10; i++) {
//10개의 Task를 실행시킨다.
executorService.execute(new Task());
}
executorService.awaitTermination(5, SECONDS);
executorService.shutdown();
}
private static class Task implements Runnable {
@Override
public void run() {
try {
//쓰레드 번호를 출력해 준다.
System.out.println(Thread.currentThread().getName());
SECONDS.sleep(1);
} catch (InterruptedException e) {
}
}
}
}
위와 같은 결과가 나오게 된다.
3개씩 스레드가 생성된 것을 확인할 수 있다.
ThreadPoolExecurator
는 지정해주는 파라미터를 통해 몇 개의 스레드를 동시에 실행할지 결정합니다.
기본적으로corePoolSize
만큼의 스레드를 실행합니다.
아직 필요한 스레드가 있을 시에 지정해준workQueue
의 사이즈만큼의 스레드를 큐에 넣습니다.
여전히 스레드가 존재하면 스레드 개수를 늘려줍니다. 이때maximumPoolSize
만큼의 스레드가 생성이 되고, 만약 이 값보다 큰 값의 스레드가 필요할 경우 에러가 발생하게 됩니다.
maximumPoolSize
만큼 증가한 스레드 수는keepAliveTime
만큼 생겼다가 다시corePoolSize
로 돌아가게 됩니다.