반응형
ThreadPool 구조 완벽 이해하기
이전 글에서:
ExecutorService executor =
Executors.newFixedThreadPool(10);
를 배웠다.
그런데 실무 면접에서는 여기서 끝나지 않는다.
오히려 진짜 많이 나오는 질문은:
ThreadPool은 내부적으로 어떻게 동작하나요?
Core Pool Size와 Max Pool Size 차이는?
Queue가 꽉 차면 어떻게 되나요?
RejectedExecutionHandler는 뭔가요?
이다.
1. ThreadPool이란?
한 줄 정의.
Thread를 미리 생성해두고 재사용하는 구조
2. 왜 필요할까?
Thread 생성은 생각보다 비싸다.
Stack 생성
TCB 생성
OS 등록
Context Switch 준비
비용 발생.
그래서
Thread 생성
↓
사용
↓
버림
을 반복하지 않고
Thread 생성
↓
계속 재사용
한다.
3. 실제 구조
Task 제출
↓
+-------------+
| Queue |
+-------------+
↓ ↓
+---------+ +---------+
|Thread 1 | |Thread 2 |
+---------+ +---------+
+---------+ +---------+
|Thread 3 | |Thread 4 |
+---------+ +---------+
4. 실제 구현체
실무 핵심.
ThreadPoolExecutor
ExecutorService는 사실 인터페이스.
실제 동작은 대부분
ThreadPoolExecutor
가 수행.
5. 생성자
ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
handler
)
6. 가장 중요한 4개
corePoolSize
maximumPoolSize
workQueue
RejectedExecutionHandler
7. 예제
ThreadPoolExecutor executor =
new ThreadPoolExecutor(
2,
4,
60,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2)
);
8. 의미
Core Thread = 2
Max Thread = 4
Queue = 2
9. 동작 순서
이 부분이 핵심.
10. Task 1 제출
현재 Thread 없음.
결과
Thread 1 생성
11. Task 2 제출
Thread 2 생성
현재
Thread 1
Thread 2
사용 중.
12. Task 3 제출
Core Thread 꽉 참.
그럼?
Queue 저장
13. Task 4 제출
Queue 저장
상태.
Thread 1 작업중
Thread 2 작업중
Queue
├─ Task3
└─ Task4
14. Task 5 제출
Queue도 꽉 참.
이제
Max Thread까지 확장
시도.
15. 결과
Thread 3 생성
16. Task 6 제출
Thread 4 생성
상태.
Thread 1
Thread 2
Thread 3
Thread 4
Queue
├─ Task3
└─ Task4
17. Task 7 제출
문제 발생.
현재
Core Thread 가득
Queue 가득
Max Thread 가득
더 이상 수용 불가.
18. 이때 등장
RejectedExecutionHandler
19. Reject Policy
작업 거부 정책.
대표적으로 4개.
20. AbortPolicy
기본값.
RejectedExecutionException
발생.
가장 많이 사용.
21. CallerRunsPolicy
호출한 Thread가 직접 실행
예:
executor.submit(...)
한 Thread가 직접 처리.
22. DiscardPolicy
그냥 버림
위험.
23. DiscardOldestPolicy
가장 오래된 Queue 제거
후
새 작업 추가.
24. keepAliveTime
매우 중요.
Core Thread 초과로 생성된 Thread.
예:
Thread 3
Thread 4
언제 제거될까?
25. keepAliveTime
60초
라면
60초 동안 놀고 있으면 제거
26. Core Thread는?
기본적으로 제거 안 됨.
즉
Core Thread
= 상시 유지
Extra Thread
= 필요 시 생성
27. 전체 흐름
매우 중요.
면접 단골.
Task 제출
↓
Core Thread 남음?
YES → Thread 생성
NO
↓
Queue 공간 있음?
YES → Queue 저장
NO
↓
Max Thread 가능?
YES → Thread 생성
NO
↓
Reject Policy 실행
28. 그림으로 이해
Task
↓
[ Core Thread ]
↓ 꽉 참
[ Queue ]
↓ 꽉 참
[ Extra Thread ]
↓ 꽉 참
[ Reject ]
29. Executors.newFixedThreadPool 문제
예:
Executors.newFixedThreadPool(10)
많이 사용하지만
실무에서는 권장 안 함.
30. 이유
내부 Queue.
LinkedBlockingQueue
사실상
무제한
크기.
31. 위험
트래픽 폭증.
Task 계속 적재
↓
메모리 증가
↓
OutOfMemoryError
32. 실무 권장
직접 생성.
new ThreadPoolExecutor(
10,
20,
60,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new ThreadPoolExecutor.AbortPolicy()
)
33. Spring에서
사실 실무는 대부분.
ThreadPoolTaskExecutor
사용.
내부는
ThreadPoolExecutor
래핑.
34. Spring 예시
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor =
new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(1000);
return executor;
}
35. 실무 튜닝 포인트
CPU 작업.
Core ≈ CPU 코어 수
I/O 작업.
Core > CPU 코어 수
가능.
36. CPU Bound
예:
암호화
압축
영상 인코딩
37. I/O Bound
예:
DB 조회
API 호출
파일 읽기
실무 대부분은
I/O Bound
에 가깝다.
38. 면접 단골 질문
Q. ThreadPoolExecutor 동작 순서는?
Core
↓
Queue
↓
Max
↓
Reject
Q. Core Pool Size란?
항상 유지되는 Thread 수
Q. Max Pool Size란?
최대 생성 가능한 Thread 수
Q. Queue가 꽉 차면?
Max Thread 생성 시도
Q. Max까지 꽉 차면?
Reject Policy 실행
Q. 왜 Executors.newFixedThreadPool을 실무에서 조심해야 하나요?
무제한 Queue
↓
OOM 위험
39. ExecutorService와 ThreadPool 연결
지금까지 흐름.
new Thread()
↓
ExecutorService
↓
ThreadPoolExecutor
↓
Core Thread
Queue
Max Thread
Reject Policy
40. 핵심 흐름 요약
Task 제출
↓
Core Thread 사용
↓ 꽉 참
Queue 저장
↓ 꽉 참
Max Thread 생성
↓ 꽉 참
Reject Policy
41. 가장 중요한 핵심 한 줄
ThreadPoolExecutor는 Core Thread → Queue → Max Thread → Reject Policy 순서로 작업을 처리하며, 이를 통해 Thread 생성 비용을 줄이고 시스템 부하를 제어한다.
42. 다음 글 예고
다음 글은
CompletableFuture
이다.
여기서부터:
Future
의 한계,
thenApply()
thenCompose()
allOf()
exceptionally()
를 통한 비동기 프로그래밍,
그리고 Spring의
@Async
와의 연결까지 배우게 된다.
반응형
'language > java' 카테고리의 다른 글
| ForkJoinPool 완벽 이해하기 (0) | 2026.06.01 |
|---|---|
| CompletableFuture 완벽 이해하기 (0) | 2026.06.01 |
| ExecutorService 완벽 이해하기 (0) | 2026.06.01 |
| Thread-safe 컬렉션 완벽 이해하기 (0) | 2026.05.29 |
| Atomic 클래스 (AtomicInteger, AtomicLong 등) 완벽 이해하기 (0) | 2026.05.29 |
댓글