1️⃣ 전통적 Executor 모델

자바에서 우리가 쓰던 방식입니다.

 
ExecutorService executor = Executors.newFixedThreadPool(10); executor.submit(() -> processSettlement());

구조

  • OS Thread 기반
  • ThreadPool 크기 고정
  • Blocking I/O면 스레드가 멈춰 있음

문제점

  • 스레드 하나당 메모리 큼 (~1MB)
  • 1,000개 요청 처리하려면 1,000 스레드 필요
  • 대기 I/O에서 리소스 낭비

그래서 풀 크기 튜닝, 큐 사이즈 조정, Rejection 정책 고민합니다.

배치 돌릴 때:

  • maxPoolSize
  • queueCapacity
  • CallerRunsPolicy

이런 거 고민하셨을 겁니다.


2️⃣ Virtual Thread 

 
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); executor.submit(() -> processSettlement());

구조

  • JVM이 관리하는 경량 스레드
  • OS Thread에 매핑됨
  • Blocking해도 다른 작업 수행 가능

차이 핵심

구분Executor (Platform Thread)                                                                       Virtual Thread
기반 OS Thread JVM 관리
메모리 매우 작음
생성 비용 비쌈 거의 없음
동시성 수 수백~수천 수십만 가능
코드 스타일 비동기/풀 튜닝 동기 코드 그대로

3️⃣ 배치/정산 관점에서 비교

예: 10,000건 정산 처리

❌ 기존 방식

  • 20개 스레드 풀
  • DB I/O 대기
  • 처리 시간 늘어남
  • 풀 크기 고민해야 함

✅ Virtual Thread

  • 10,000개 작업 그냥 던짐
  • 각 작업은 동기 코드
  • 대기 I/O 동안 다른 작업 실행
  • 풀 튜닝 거의 불필요

4️⃣ 언제 Executor가 낫나?

  • CPU 연산 위주
  • 병렬 계산
  • ForkJoinPool 사용 시
  • 라이브러리 호환성 문제 있을 때

5️⃣ 상황 적용

정산/배치 특징:

  • DB I/O 많음
  • 외부 API 호출 있음
  • 부분환불, 멱등성 체크

이건 전형적인 I/O bound

👉 Virtual Thread 궁합 좋음


6️⃣ 코루틴이랑 뭐가 다르냐

코틀린 코루틴은:

  • 완전 다른 스케줄링 모델
  • suspend 기반
  • non-blocking 설계 필요

Virtual Thread는:

  • 기존 동기 코드 그대로 사용
  • 학습 비용 거의 없음

7️⃣ 설계자 관점 핵심

- 이 작업은 CPU-bound인가?

- I/O-bound인가?

- 스레드 수를 내가 튜닝해야 하나?

- 코드 단순성이 중요한가?

LIST

+ Recent posts