피드로 돌아가기
Project Loom: Java's Virtual Threads – From Nightmares to Modern Concurrency Bliss
Dev.toDev.to
Backend

Project Loom Virtual Threads 도입으로 1MB 스택의 OS 스레드 대신 수백만 개 경량 스레드로 동시성 문제 해소함

Project Loom: Java's Virtual Threads – From Nightmares to Modern Concurrency Bliss

Felipe Stanzani2026년 4월 1일7intermediate

Context

2006년 Delphi 7의 Platform Thread 기반 물류 시스템에서 수백 개 동시 트럭 처리 시 메모리 과사용과 컨텍스트 스위칭 성능 저하 문제가 발생함. Java의 기존 Thread와 ExecutorService는 OS 스레드와 1:1 매핑되어 ~1MB 스택을 소비하고 블로킹 시 전체 OS 스레드를 점유하는 구조적 한계를 가짐.

Technical Solution

  • Virtual Threads: JVM이 관리하는 경량 스레드로 수 KB 동적 스택 사용, 수백만 개 생성 가능함
  • Many:1 매핑: 복수의 Virtual Thread가 단일 Carrier Thread에 마운트되어 OS 스레드 자원 소비를 최소화함
  • JVM 스케줄러: Virtual Thread 블로킹 시 Carrier Thread를 언마운트하여 다른 Virtual Thread를 마운트하는 work-stealing 방식으로 동작함
  • StructuredTaskScope: try-with-resources 패턴과 유사한 스코프 기반 동시성 관리로 스레드 생명주기 자동 제어함
  • ScopedValue: ThreadLocal의 대안으로 동시성 환경에서 더 안전한 데이터 공유 메커니즘 제공함

Impact

기존 Platform Thread 방식(200-500 스레드 제한)에서 Virtual Thread 방식(100만 개 이상 동시 처리)으로 동시성 처리량이 수천 배 증가함. Thread.sleep(1000) 같은 블로킹 호출이 Carrier Thread를 점유하지 않아 I/O 바운드 작업에서 스레드 낭비가 제거됨.

Key Takeaway

Virtual Threads는 coroutines나 reactive streams 같은 새로운 추상화가 아닌 기존 Thread API와 완전 호환되는 진짜 Thread 객체임. I/O 바운드 워크로드에서 별도의 스레드 풀 튜닝 없이 기존 코드를 최소 변경으로 확장성 있는 동시성으로 전환 가능함.


I/O 바운드 REST API나 데이터베이스 호출이 많은 백엔드 서비스에서 Executors.newVirtualThreadPerTaskExecutor()로 기존 ExecutorService를 대체하면 스레드 풀 크기 튜닝 없이 수천-수백만 동시 요청을 처리할 수 있음. Structured Concurrency 적용 시 try-with-resources 패턴으로 스레드リー크와孤儿タスク를 자동으로 방지할 수 있음.

원문 읽기