Unit 7.5 — 스레드 풀의 종류

Psj·2026년 5월 26일

F-lab

목록 보기
149/239

Unit 7.5 — 스레드 풀의 종류

F-LAB JAVA · 4주차 · Phase 7 · Executor 프레임워크


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • newFixedThreadPool 의 구성과 특성은?
  • newCachedThreadPool 의 구성과 위험은?
  • newSingleThreadExecutor 의 특성 (순차 보장) 은?
  • newScheduledThreadPool 의 용도는?
  • newWorkStealingPool (ForkJoin 기반) 은?
  • newVirtualThreadPerTaskExecutor (Java 21+) 는?
  • SingleThreadExecutor vs FixedThreadPool(1) 의 차이는?
  • 각 풀의 내부 ThreadPoolExecutor 설정 은?
  • 언제 어느 풀을 쓰나 ?

🎯 핵심 한 문장

Executors 는 자주 쓰는 스레드 풀을 제공하며, Fixed (고정 크기), Cached (동적), Single (단일·순차), Scheduled (예약), WorkStealing (ForkJoin), Virtual (Java 21+) 의 종류가 있다.
newFixedThreadPool(n) 은 고정 n개 스레드와 무제한 큐로 안정적이지만 큐 적체 시 OOM 위험이 있고, newCachedThreadPool() 은 0~무제한 스레드와 SynchronousQueue 로 폭발적 부하에 스레드가 무한 생성될 위험이 있다.
newSingleThreadExecutor() 는 단일 스레드로 작업을 순차 실행하여 순서를 보장하며, FixedThreadPool(1) 과 달리 재구성이 불가능 하도록 래핑되어 있다.
newScheduledThreadPool(n) 은 지연·반복 실행에 쓰이고, newWorkStealingPool() 은 ForkJoinPool 기반으로 각 스레드가 자기 큐를 가지고 일을 훔쳐오는 (work stealing) 방식이다.
Java 21+ 의 newVirtualThreadPerTaskExecutor() 는 작업마다 경량 가상 스레드를 생성하여 I/O 바운드 작업에 매우 효율적이다.

비유 — 다양한 운영 방식의 가게

스레드 풀 종류 = 가게 운영 방식:

Fixed (고정 직원):
  - 직원 N명 고정
  - 안정적, 예측 가능
  - 손님 많아도 대기열 무한 (OOM)

Cached (탄력 직원):
  - 손님 오면 즉시 채용
  - 한가하면 해고
  - 폭증 시 무한 채용 (OOM)

Single (1인 가게):
  - 사장 혼자
  - 순서대로 처리 (순차 보장)

Scheduled (예약 가게):
  - "30분 후", "매시간" 처리

WorkStealing (협동 직원):
  - 각자 일감
  - 한가하면 남의 일 도움 (훔침)

Virtual (Java 21+ 무한 알바):
  - 손님마다 가상 알바 (초경량)
  - I/O 대기 많을 때 효율

→ 용도별 풀 선택: Fixed(안정), Cached(탄력), Single(순차), Scheduled(예약), WorkStealing(분산), Virtual(I/O).


🧭 9개 섹션 로드맵

1. newFixedThreadPool
2. newCachedThreadPool
3. newSingleThreadExecutor
4. newScheduledThreadPool
5. newWorkStealingPool
6. newVirtualThreadPerTaskExecutor
7. Single vs Fixed(1)
8. 풀 선택 가이드
9. 면접 + 자기 점검

1️⃣ newFixedThreadPool

1.1 정의

newFixedThreadPool(n):

  고정 n개 스레드 풀.
  - core == max == n
  - 무제한 큐 (LinkedBlockingQueue)

1.2 내부 구성

// newFixedThreadPool(n) 내부
public static ExecutorService newFixedThreadPool(int n) {
    return new ThreadPoolExecutor(
        n, n,                          // core == max
        0L, TimeUnit.MILLISECONDS,     // keepAlive 0
        new LinkedBlockingQueue<>()    // 무제한 큐
    );
}

1.3 특성

Fixed 특성:

  - 스레드 수 고정 (n)
  - 작업 많으면 큐 대기
  - 안정적 (예측 가능)

위험:
  - 무제한 큐
  - 작업 폭증 시 OOM

1.4 사용

ExecutorService executor = Executors.newFixedThreadPool(10);

for (int i = 0; i < 1000; i++) {
    executor.submit(() -> doWork());
    // 10 스레드, 990 큐 대기
}

1.5 적합한 경우

Fixed 적합:

  - 안정적 부하
  - 동시성 제한 필요
  - 예측 가능한 작업 수

CPU 바운드:
  - n = 코어 수 + 1

1.6 ILIC 의 맥락

@Service
public class FixedThreadPoolUsage {
    
    private final int cores = Runtime.getRuntime().availableProcessors();
    
    // 운임 계산 (CPU 바운드)
    private final ExecutorService cpuPool = 
        Executors.newFixedThreadPool(cores + 1);
    
    public void calculateBatch(List<Shipment> shipments) {
        for (Shipment shipment : shipments) {
            cpuPool.submit(() -> calculateFreight(shipment));
            // 고정 스레드, 큐 대기
        }
    }
    
    // 주의: 무제한 큐 → 작업 폭증 시 OOM
    // 운영은 직접 ThreadPoolExecutor (제한 큐) 권장
    
    private BigDecimal calculateFreight(Shipment s) { return s.getWeight(); }
}

1.7 자기 점검 답변

newFixedThreadPool의 구성과 특성은?

:
1. 구성:

  • core == max == n
  • 무제한 큐
  1. 특성:

    • 스레드 고정
    • 안정적
  2. 위험:

    • 무제한 큐 OOM
  3. 적합:

    • 안정 부하
    • CPU 바운드

2️⃣ newCachedThreadPool

2.1 정의

newCachedThreadPool():

  동적 크기 풀.
  - core 0, max 무제한
  - SynchronousQueue (직접 전달)
  - 60초 유휴 정리

2.2 내부 구성

// newCachedThreadPool() 내부
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(
        0, Integer.MAX_VALUE,          // core 0, max 무제한!
        60L, TimeUnit.SECONDS,         // 60초 정리
        new SynchronousQueue<>()       // 직접 전달
    );
}

2.3 특성

Cached 특성:

  - 스레드 동적 (0 ~ 무제한)
  - 작업 오면 스레드 (재사용 또는 생성)
  - 유휴 60초 후 정리

장점:
  - 탄력적
  - 짧은 작업 효율

2.4 위험

Cached 위험:

  max 무제한:
    - 작업 폭증 시
    - 스레드 무한 생성
    - OOM (스레드 폭발)

→ 부하 예측 어려우면 위험

2.5 적합한 경우

Cached 적합:

  - 짧은 비동기 작업
  - 부하 변동
  - 작업 수 제한적

부적합:
  - 부하 폭증 가능
  - 긴 작업

2.6 ILIC 의 맥락

@Service
public class CachedThreadPoolUsage {
    
    // ⚠️ Cached — 짧은 작업, 제한적 부하만
    private final ExecutorService cachedPool = 
        Executors.newCachedThreadPool();
    
    public void quickTask(Runnable task) {
        cachedPool.submit(task);
        // 짧은 작업에 탄력적
    }
    
    // ❌ 위험 — 폭증 가능한 곳
    public void handleRequests(List<Request> requests) {
        // requests 가 많으면 스레드 폭발 (OOM)
        // → Fixed 또는 제한된 풀 권장
    }
    
    // ✓ 안전 대안 — 제한된 풀
    private final ExecutorService boundedPool = new ThreadPoolExecutor(
        0, 50,                          // max 제한 (50)
        60L, TimeUnit.SECONDS,
        new SynchronousQueue<>(),
        new ThreadPoolExecutor.CallerRunsPolicy()
    );
    
    record Request(String data) {}
}

2.7 자기 점검 답변

newCachedThreadPool의 구성과 위험은?

:
1. 구성:

  • core 0, max 무제한
  • SynchronousQueue
  • 60초 정리
  1. 특성:

    • 동적
    • 탄력적
  2. 위험:

    • 무제한 스레드
    • OOM
  3. 적합:

    • 짧은 작업
    • 제한적 부하

3️⃣ newSingleThreadExecutor

3.1 정의

newSingleThreadExecutor():

  단일 스레드 풀.
  - 스레드 1개
  - 작업 순차 실행
  - 순서 보장

3.2 내부 구성

// newSingleThreadExecutor() 내부
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService(
        new ThreadPoolExecutor(
            1, 1,                          // 1개
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>()    // 무제한 큐
        )
    );
    // 래핑 (재구성 방지)
}

3.3 순차 보장

순차 실행 보장:

  스레드 1개:
    - 작업이 순서대로
    - 동시 실행 X
    - 이전 완료 후 다음

용도:
  - 순서 중요한 작업
  - 직렬화 필요

3.4 특성

Single 특성:

  - 1개 스레드
  - 순차 (FIFO)
  - 스레드 죽으면 재생성
  - 무제한 큐

장점:
  - 순서 보장
  - 동기화 불필요 (단일)

3.5 스레드 재생성

스레드 재생성:

  작업 중 예외로 스레드 죽으면:
    - 새 스레드 자동 생성
    - 다음 작업 계속

  → 안정적 (1개 유지)

3.6 ILIC 의 맥락

@Service
public class SingleThreadExecutorUsage {
    
    // 순차 처리 (순서 중요)
    private final ExecutorService sequentialExecutor = 
        Executors.newSingleThreadExecutor();
    
    // 감사 로그 (순서 보장)
    public void logAudit(AuditEvent event) {
        sequentialExecutor.submit(() -> {
            auditRepository.save(event);
            // 순서대로 기록 (단일 스레드)
        });
    }
    
    // 상태 머신 (순차 전이)
    public void updateState(Shipment shipment, Status newStatus) {
        sequentialExecutor.submit(() -> {
            shipment.transitionTo(newStatus);
            // 순차 처리 → 상태 일관성
            // 동기화 불필요 (단일 스레드)
        });
    }
    
    enum Status { CREATED, BOOKED, SHIPPED }
    record AuditEvent(String action) {}
}

3.7 자기 점검 답변

newSingleThreadExecutor의 특성은?

:
1. 정의:

  • 단일 스레드
  • 순차 실행
  1. 순차 보장:

    • FIFO
    • 동시 실행 X
  2. 재생성:

    • 죽으면 새로
  3. 장점:

    • 순서 보장
    • 동기화 불필요

4️⃣ newScheduledThreadPool

4.1 정의

newScheduledThreadPool(n):

  예약/반복 실행 풀.
  - ScheduledThreadPoolExecutor
  - 지연 실행
  - 주기 실행

4.2 내부 구성

// newScheduledThreadPool(n) 내부
public static ScheduledExecutorService newScheduledThreadPool(int n) {
    return new ScheduledThreadPoolExecutor(n);
    // DelayedWorkQueue 사용
}

4.3 메서드 (Unit 7.2 복습)

ScheduledExecutorService scheduler = 
    Executors.newScheduledThreadPool(2);

// 지연
scheduler.schedule(task, 5, TimeUnit.SECONDS);

// 주기 (시작 간격)
scheduler.scheduleAtFixedRate(task, 0, 10, TimeUnit.SECONDS);

// 지연 (완료 후 간격)
scheduler.scheduleWithFixedDelay(task, 0, 10, TimeUnit.SECONDS);

4.4 특성

Scheduled 특성:

  - 시간 기반 실행
  - DelayQueue (우선순위)
  - 지연/주기

용도:
  - 주기 작업
  - 예약 작업
  - 타임아웃

4.5 Timer 대비 장점

ScheduledExecutor vs Timer:

Timer (구식):
  - 단일 스레드
  - 예외 시 전체 중단
  - 시간 부정확

ScheduledExecutor:
  - 멀티 스레드
  - 예외 격리
  - 정확

→ ScheduledExecutor 권장

4.6 ILIC 의 맥락

@Service
public class ScheduledThreadPoolUsage {
    
    private final ScheduledExecutorService scheduler = 
        Executors.newScheduledThreadPool(2, r -> {
            Thread t = new Thread(r, "scheduler");
            t.setDaemon(true);
            return t;
        });
    
    @PostConstruct
    public void startSchedules() {
        // 만료 예약 정리 (5분마다)
        scheduler.scheduleAtFixedRate(
            this::cleanExpiredBookings, 0, 5, TimeUnit.MINUTES);
        
        // 추적 정보 갱신 (완료 후 1분)
        scheduler.scheduleWithFixedDelay(
            this::refreshTracking, 0, 1, TimeUnit.MINUTES);
        
        // 일일 리포트 (지연 실행)
        scheduler.schedule(
            this::generateDailyReport, 
            secondsUntilMidnight(), TimeUnit.SECONDS);
    }
    
    private void cleanExpiredBookings() { }
    private void refreshTracking() { }
    private void generateDailyReport() { }
    private long secondsUntilMidnight() { return 3600; }
}

4.7 자기 점검 답변

newScheduledThreadPool의 용도는?

:
1. 정의:

  • 예약/반복 실행
  • ScheduledThreadPoolExecutor
  1. 메서드:

    • schedule (지연)
    • scheduleAtFixedRate/WithFixedDelay
  2. 특성:

    • 시간 기반
    • DelayQueue
  3. vs Timer:

    • 멀티 스레드, 예외 격리

5️⃣ newWorkStealingPool

5.1 정의

newWorkStealingPool():

  ForkJoinPool 기반 풀 (Java 8+).
  - 각 스레드 자기 큐
  - work stealing (일 훔치기)
  - 병렬도 = CPU 코어

5.2 내부 구성

// newWorkStealingPool() 내부
public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool(
        Runtime.getRuntime().availableProcessors(),
        ForkJoinPool.defaultForkJoinWorkerThreadFactory,
        null, true
    );
}

5.3 work stealing

work stealing (일 훔치기):

  각 스레드 자기 작업 큐 (deque):
    - 자기 큐에서 작업 (LIFO)
    - 자기 큐 비면
    - 다른 스레드 큐에서 훔침 (FIFO)

효과:
  - 부하 분산
  - 유휴 스레드 활용

5.4 시각화

work stealing:

스레드1 큐: [작업, 작업, 작업]
스레드2 큐: [] (비음)
              ↓ 훔침
스레드2: 스레드1 큐에서 작업 훔침

  → 부하 자동 분산

5.5 특성

WorkStealing 특성:

  - 분산 큐 (스레드별)
  - 일 훔치기
  - 병렬 작업 효율

용도:
  - 분할 정복 (ForkJoin)
  - 많은 작은 작업
  - 재귀 작업

5.6 ILIC 의 맥락

@Service
public class WorkStealingPoolUsage {
    
    // work stealing — 병렬 처리
    private final ExecutorService workStealingPool = 
        Executors.newWorkStealingPool();
    
    public void processParallel(List<Shipment> shipments) {
        List<CompletableFuture<Void>> futures = shipments.stream()
            .map(s -> CompletableFuture.runAsync(
                () -> process(s), workStealingPool))
            .toList();
        
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .join();
        // 부하 자동 분산 (work stealing)
    }
    
    // 병렬 스트림도 ForkJoinPool 사용
    public BigDecimal totalFreight(List<Shipment> shipments) {
        return shipments.parallelStream()   // 공통 ForkJoinPool
            .map(this::calculateFreight)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    private void process(Shipment s) { }
    private BigDecimal calculateFreight(Shipment s) { return s.getWeight(); }
}

5.7 자기 점검 답변

newWorkStealingPool은?

:
1. 정의:

  • ForkJoinPool 기반
  • 병렬도 = 코어
  1. work stealing:

    • 스레드별 큐
    • 유휴 시 훔침
  2. 효과:

    • 부하 분산
  3. 용도:

    • 분할 정복
    • 많은 작은 작업

6️⃣ newVirtualThreadPerTaskExecutor

6.1 정의

newVirtualThreadPerTaskExecutor() (Java 21+):

  작업마다 가상 스레드 생성.
  - 경량 스레드 (Virtual Thread)
  - 작업당 1개
  - I/O 바운드 효율

6.2 가상 스레드

가상 스레드 (Virtual Thread):

  - JVM 관리 경량 스레드
  - OS 스레드 (캐리어) 에 매핑
  - 블로킹 시 캐리어 양보
  - 매우 가벼움 (수백만 개)

6.3 내부

// newVirtualThreadPerTaskExecutor() (Java 21+)
ExecutorService executor = 
    Executors.newVirtualThreadPerTaskExecutor();

// 작업마다 가상 스레드
executor.submit(() -> {
    // I/O 작업 (블로킹)
    // 캐리어 스레드 양보 (효율)
});

6.4 플랫폼 스레드와 차이

가상 스레드 vs 플랫폼 스레드:

플랫폼 스레드:
  - OS 스레드 (1:1)
  - 무거움 (1MB 스택)
  - 수천 개 한계

가상 스레드:
  - JVM 관리 (M:N)
  - 가벼움 (수KB)
  - 수백만 개
  - 블로킹 시 양보

6.5 I/O 효율

I/O 바운드 효율:

  플랫폼 스레드:
    - I/O 대기 시 스레드 블록
    - 스레드 수 한계

  가상 스레드:
    - I/O 대기 시 캐리어 양보
    - 다른 작업 진행
    - 수백만 동시 I/O

→ I/O 바운드에 혁신적

6.6 ILIC 의 맥락

@Service
public class VirtualThreadUsage {
    
    // Java 21+ 가상 스레드 (I/O 바운드)
    private final ExecutorService virtualExecutor = 
        Executors.newVirtualThreadPerTaskExecutor();
    
    // 외부 API 호출 (I/O 바운드)
    public void fetchTrackingForAll(List<Shipment> shipments) {
        List<Future<TrackingInfo>> futures = shipments.stream()
            .map(s -> virtualExecutor.submit(() -> 
                trackingApi.fetch(s.getBlNo())))   // I/O 블로킹
            .toList();
        // 수천 개 동시 I/O (가상 스레드)
        // 플랫폼 스레드라면 풀 고갈
        // 가상 스레드는 블로킹 시 양보 → 효율
    }
    
    // 주의: CPU 바운드는 가상 스레드 이점 적음
    // (플랫폼 스레드 풀 권장)
    
    record TrackingInfo() {}
}

6.7 자기 점검 답변

newVirtualThreadPerTaskExecutor는?

:
1. 정의:

  • Java 21+
  • 작업당 가상 스레드
  1. 가상 스레드:

    • 경량 (수KB)
    • M:N 매핑
  2. I/O 효율:

    • 블로킹 시 양보
    • 수백만 동시
  3. 용도:

    • I/O 바운드
    • (CPU 바운드는 이점 적음)

7️⃣ Single vs Fixed(1)

7.1 핵심 차이

SingleThreadExecutor vs FixedThreadPool(1):

  둘 다 스레드 1개.

차이:
  SingleThreadExecutor:
    - 재구성 불가 (래핑됨)
    - setCorePoolSize 등 X

  FixedThreadPool(1):
    - 재구성 가능
    - 나중에 크기 변경 가능

7.2 재구성 차이

// SingleThreadExecutor — 재구성 불가
ExecutorService single = Executors.newSingleThreadExecutor();
// FinalizableDelegatedExecutorService 로 래핑
// ThreadPoolExecutor 메서드 접근 X
// ((ThreadPoolExecutor) single).setCorePoolSize(5);  // 불가!

// FixedThreadPool(1) — 재구성 가능
ExecutorService fixed = Executors.newFixedThreadPool(1);
((ThreadPoolExecutor) fixed).setCorePoolSize(5);   // 가능
// 1 → 5 변경 가능 (순차 보장 깨짐)

7.3 왜 래핑

SingleThreadExecutor 래핑 이유:

  순차 보장을 위해:
    - 크기 변경 막음 (1 유지)
    - 외부에서 못 늘림

  → 순서 보장 의도 보호

7.4 의미

의미:

  SingleThreadExecutor:
    - "항상 1개" 보장
    - 순차 의도 명확

  FixedThreadPool(1):
    - 현재 1개
    - 나중에 변경 가능 (의도 불명확)

7.5 선택

선택:

순차 보장 필요:
  → SingleThreadExecutor
  (변경 불가, 안전)

유연성 필요:
  → FixedThreadPool(1)
  (나중에 늘릴 수도)

7.6 ILIC 의 맥락

@Service
public class SingleVsFixedOne {
    
    // 순차 보장 — SingleThreadExecutor
    private final ExecutorService sequential = 
        Executors.newSingleThreadExecutor();
    // 항상 1개 (순서 보장, 변경 불가)
    
    public void processInOrder(Shipment shipment) {
        sequential.submit(() -> {
            // 순서대로 (단일 스레드 보장)
            updateStatus(shipment);
        });
    }
    
    // 유연성 — Fixed(1) (나중에 확장 가능)
    private final ExecutorService flexible = 
        Executors.newFixedThreadPool(1);
    
    public void scaleUp() {
        ((ThreadPoolExecutor) flexible).setCorePoolSize(4);
        // 1 → 4 확장 (순차 보장 깨짐)
    }
    
    private void updateStatus(Shipment s) { }
}

7.7 자기 점검 답변

SingleThreadExecutor vs FixedThreadPool(1) 차이는?

:
1. 공통:

  • 스레드 1개
  1. Single:

    • 재구성 불가 (래핑)
    • 순차 보장
  2. Fixed(1):

    • 재구성 가능
    • 나중에 변경
  3. 선택:

    • 순차 보장: Single
    • 유연성: Fixed(1)

8️⃣ 풀 선택 가이드

8.1 선택 표

용도주의
Fixed안정 부하, CPU무제한 큐
Cached짧은 작업, 탄력무제한 스레드
Single순차 보장단일
Scheduled예약/반복-
WorkStealing병렬, 분할정복-
VirtualI/O 바운드Java 21+

8.2 부하 유형별

부하 유형별:

CPU 바운드:
  - Fixed (코어 + 1)
  - WorkStealing

I/O 바운드:
  - 더 큰 풀
  - Virtual (Java 21+)

순차:
  - Single

예약:
  - Scheduled

8.3 직접 생성 권장

직접 생성 권장:

  Executors 팩토리:
    - 편리하지만 위험
    - 무제한 큐/스레드

  운영 환경:
    - 직접 ThreadPoolExecutor
    - 제한된 큐
    - 명시적 거부 정책

8.4 안전한 생성

// ✓ 운영용 — 직접 생성
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    cores,                              // core
    cores * 2,                          // max
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000),    // 제한 큐
    namedThreadFactory("worker"),       // 명명
    new ThreadPoolExecutor.CallerRunsPolicy()  // 백프레셔
);

8.5 현대적 선택

현대적 선택 (Java 21+):

I/O 바운드:
  - Virtual Thread (newVirtualThreadPerTaskExecutor)
  - 풀 불필요 (작업당)

CPU 바운드:
  - Fixed (플랫폼 스레드)
  - 또는 WorkStealing

→ I/O 는 Virtual, CPU 는 플랫폼

8.6 ILIC 의 맥락

@Configuration
public class PoolSelectionConfig {
    
    private final int cores = Runtime.getRuntime().availableProcessors();
    
    // CPU 바운드 (운임 계산)
    @Bean("cpuPool")
    public ExecutorService cpuPool() {
        return new ThreadPoolExecutor(
            cores + 1, cores + 1, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1000),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
    
    // I/O 바운드 (외부 API) — Java 21+ Virtual
    @Bean("ioPool")
    public ExecutorService ioPool() {
        return Executors.newVirtualThreadPerTaskExecutor();
        // 수천 동시 I/O 효율
    }
    
    // 예약 작업
    @Bean("scheduler")
    public ScheduledExecutorService scheduler() {
        return Executors.newScheduledThreadPool(2);
    }
    
    // 순차 작업 (감사 로그)
    @Bean("sequential")
    public ExecutorService sequential() {
        return Executors.newSingleThreadExecutor();
    }
}

8.7 자기 점검 답변

풀 선택 가이드는?

:
1. 유형별:

  • CPU: Fixed/WorkStealing
  • I/O: Virtual (Java 21+)
  • 순차: Single
  • 예약: Scheduled
  1. 직접 생성:

    • 운영은 ThreadPoolExecutor
    • 제한 큐
  2. 현대:

    • I/O: Virtual
    • CPU: 플랫폼
  3. 권장:

    • 용도별 선택

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
Fixed?고정, 무제한 큐
Cached?동적, 무제한 스레드
Single?단일, 순차
Scheduled?예약/반복
WorkStealing?ForkJoin, 일 훔치기
Virtual?Java 21+, I/O 효율
Single vs Fixed(1)?재구성 불가 vs 가능
Cached 위험?무제한 스레드 OOM
직접 생성?운영 권장
I/O 풀?Virtual 또는 큰 풀

9.2 자기 점검 체크리스트

Fixed

  • 고정
  • 무제한 큐

Cached

  • 동적
  • 무제한 스레드

Single

  • 순차
  • 재구성 불가

Scheduled

  • 예약/반복

WorkStealing

  • ForkJoin
  • 일 훔치기

Virtual

  • Java 21+
  • I/O 효율

선택

  • 유형별
  • 직접 생성

9.3 추가 심화 질문

Q1: 병렬 스트림과 ForkJoinPool?

답:

  • parallelStream() 은 공통 ForkJoinPool
  • common pool (전역 공유)
  • 블로킹 작업 주의 (풀 고갈)
  • 커스텀 풀 권장 (블로킹 시)

Q2: Cached 의 SynchronousQueue?

답:

  • 크기 0 (저장 X)
  • 작업이 바로 스레드로
  • 받을 스레드 없으면 생성
  • → 무제한 스레드

Q3: Virtual Thread 의 캐리어?

답:

  • 플랫폼 스레드 (ForkJoinPool)
  • 가상 스레드 실행
  • 블로킹 시 가상 스레드 분리
  • 캐리어는 다른 가상 스레드

Q4: 풀 크기 동적 조정?

답:

  • setCorePoolSize/setMaximumPoolSize
  • 런타임 변경
  • 부하 따라
  • Single 은 불가 (래핑)

Q5: Spring 의 ThreadPoolTaskExecutor?

답:

  • Spring 의 래퍼
  • ThreadPoolExecutor 기반
  • @Async 와 연동
  • 설정 편의

🎯 핵심 요약 — 3줄 정리

1. 풀 종류

  • Fixed (고정), Cached (동적), Single (순차)
  • Scheduled (예약), WorkStealing (분산), Virtual (I/O)

2. 위험

  • Fixed: 무제한 큐 OOM
  • Cached: 무제한 스레드 OOM
  • → 직접 ThreadPoolExecutor (제한)

3. 선택

  • CPU: Fixed/WorkStealing
  • I/O: Virtual (Java 21+) 또는 큰 풀
  • 순차: Single, 예약: Scheduled

📚 다음으로...

Unit 7.6 — 작업 큐와 거부 정책

이번 Unit에서 풀 종류를 봤다면, 다음은 작업 큐와 거부 정책 (상세).

  • LinkedBlockingQueue / ArrayBlockingQueue / SynchronousQueue
  • 거부 정책 4가지 상세
  • 큐와 정책 조합

Phase 7 진행 상황

🚀 Phase 7 — Executor 프레임워크 (★ 2차 정점)
  ✅ Unit 7.1 스레드 풀의 필요성
  ✅ Unit 7.2 Executor와 ExecutorService
  ✅ Unit 7.3 Future와 Callable
  ✅ Unit 7.4 ThreadPoolExecutor 내부 (★ 마스터)
  ✅ Unit 7.5 스레드 풀 종류 ← 여기
  ⏭ Unit 7.6 작업 큐와 거부 정책
  ⏭ Unit 7.7 스레드 풀 종료

4주차 누적 진행

✅ Phase 1~6 (25 Unit, 1차 정점 완료)
🚀 Phase 7 — Executor (5/7 진행) ★ 2차 정점

총: 30/35 Unit
profile
Software Developer

0개의 댓글