728x90
Java Virtual Thread와 ThreadPoolExecutor 비교
Java 21부터 가상 스레드(Virtual Thread)(이하 가상스레드)가 도입되면서, 기존 ThreadPoolExecutor(이하 스레드풀) 방식과 비교해 스레드 관리 전략에 큰 변화가 생겼습니다. 이번 글에서는 스레드풀과 가상 스레드의 동작 방식을 코드로 비교하며, 언제 어떤 방식을 써야 하는지 정리해보겠습니다.
1. ThreadPoolExecutor 동작 원리
우리가 일반적으로 사용하는 ThreadPoolExecutor 또는 ThreadTaskExecutor의 execute() 코드는 다음과 같습니다.
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (!isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
동작 방식
- 현재 실행 중인 worker 수 확인
- corePoolSize보다 작으면 새 스레드 생성
- 아니면 작업 큐(workQueue)에 추가 후 대기
- 스레드와 큐가 모두 꽉 차면 reject 실행
즉, ThreadPoolExecutor는 스레드를 미리 생성해 두고 재사용하는 구조이며, 내부적으로 event-loop 방식과 비슷하게 동작합니다.
2. Virtual Thread 동작 원리
반면, 가상 스레드를 사용하는 Executor의 execute() 구현은 매우 단순합니다.
public void execute(Runnable task) {
this.virtualThreadFactory.newThread(task).start();
}
동작 방식
- 새로운 가상 스레드를 매번 생성
- 스레드 풀을 사용하지 않고 즉시 실행 후 종료
- corePoolSize, maxPoolSize, queue 설정이 필요 없음
즉, Virtual Thread는 재사용하지 않고 요청마다 새로 생성하는 모델입니다.
3. ThreadPoolExecutor vs Virtual Thread 비교
| 스레드 생성 방식 | 미리 생성 후 재사용 | 요청마다 새로 생성 |
| 설정 필요 여부 | Core, Max, Queue 설정 필요 | 설정 불필요 |
| 동시성 처리 | 제한적, 스레드 수에 따라 달라짐 | 매우 많은 동시성 처리 가능 |
| 메모리 사용량 | 상대적으로 안정적 | 많은 스레드 생성 시 OOM 위험 |
| 제어 가능성 | 스레드 개수, 큐 크기 제어 가능 | 제어 어려움 |
4. Virtual Thread의 장점과 단점
장점
- 스레드 풀 설정이 필요 없어 코드가 단순해짐
- 수천 개 이상의 I/O 요청을 병렬로 쉽게 처리 가능
- 컨텍스트 스위칭 비용이 낮음
단점
- 스레드 생성 제한이 없어 메모리 폭증 위험
5. 정리
- ThreadPoolExecutor → 스레드를 미리 만들고 재사용하는 방식
- Virtual Thread → 요청마다 스레드를 매번 새로 생성하는 방식
- Virtual Thread는 I/O-bound 작업에서 큰 강점을 발휘하지만,메모리 관리를 반드시 고려해야 합니다.
단순히 가상 스레드니까 무조건 좋다. 가 아니라,
작업 성격에 맞게 ThreadPoolExecutor와 Virtual Thread를 적절히 혼용하는 전략이 필요합니다.
번외) virtualThread에서는 최소 corePoolSize를 정할 수 없기 때문에, 매번 새로 생성을 해주어야하지만
ThreadPoolExecutor에서는 최소 corePoolSize를 지정 할 수 있기 때문에 가용 가능한 스레드가 많다면 오히려 처리 속도가 더 빠를 수 있어 적절하게 판단하고 사용하는 것이 중요합니다.
'Language > Java' 카테고리의 다른 글
| 함수형 프로그래밍과 일급 객체란 (0) | 2023.06.04 |
|---|---|
| Logger에서 hibernate SQL 로그 출력이 안될 경우 (0) | 2023.05.18 |
| 가비지 콜렉션(Garbage Collection) (0) | 2023.04.22 |
| JVM (0) | 2023.04.21 |
| enum의 Enum 상수 객체의 변수 사용과 생성 (1) | 2023.04.12 |