JAVA에서 Platform Thread와 Virtual Thread
Source: Dev.to
Platform Threads
Java에서 고전적인 스레드 모델을 플랫폼 스레드라고 합니다. 이는 운영 체제에 직접 매핑되는 전통적인 스레드입니다.
Thread thread = new Thread(() -> {
doWork();
});
thread.start(); // Starts a new platform thread
처음에는 강력하게 느껴집니다—실제 병렬 작업과 멀티태스킹을 얻을 수 있기 때문이죠. 하지만 다음과 같은 상황에서 문제가 발생합니다:
- 스레드를 너무 많이 생성 → 애플리케이션이 느려짐.
- 수천 개의 요청을 처리 → 스레드 풀 고갈.
- 블로킹 I/O 수행 → 스레드가 외부 작업을 기다리며 대기 상태가 됨.
왜일까요? 플랫폼 스레드는 OS 스레드에 직접 매핑되기 때문입니다:
- 하나의 Java 스레드 = 하나의 OS 스레드.
- OS 스레드는 비용이 많이 듭니다(큰 스택, 스케줄링 오버헤드).
그 결과 개발자들은 다음과 같은 방법을 사용하게 됩니다:
- 고정 크기 스레드 풀.
- 비동기 API.
- 리액티브 프로그래밍.
- 복잡한 실행 모델.
이러한 우회 방법은 욕구에서 나온 것이 아니라 플랫폼 스레드의 확장성 한계 때문에 생깁니다.
핵심 문제
I/O 작업 중 스레드는:
- 계산을 수행하지 않는다.
- CPU를 사용하지 않는다.
- 단지 외부 작업이 완료될 때까지 기다린다.
그럼에도 불구하고 희소한 OS 자원을 차지합니다. 바로 여기서 가상 스레드가 등장합니다.
Virtual Threads — Lightweight & Scalable
가상 스레드는 JVM이 관리하는 경량 스레드로, OS 스레드의 오버헤드 없이 수백만 개의 동시 작업을 수행할 수 있습니다.
Thread thread = Thread.startVirtualThread(() -> {
doWork();
});
- 플랫폼 스레드와 동일한 프로그래밍 모델 및 블로킹 스타일.
- JVM에 의해 생성·스케줄링되며 OS 스레드에 영구적으로 연결되지 않음.
- 플랫폼 스레드에 비해 매우 저렴함.
실제로 일어나는 일
- Running: 가상 스레드는 carrier(플랫폼) 스레드에 탑재됩니다.
- Blocking: 가상 스레드가 park 상태가 되면 carrier 스레드가 해제됩니다.
- Unblocked: 가상 스레드는 사용 가능한 어떤 carrier 스레드에서도 재개됩니다.
즉, 차단되는 것은 가상 스레드 자체뿐이며, 기반이 되는 OS 스레드는 차단되지 않습니다. 이는 플랫폼 스레드의 확장성 병목을 해소합니다:
- 블로킹 I/O가 더 이상 OS 스레드를 낭비하지 않음.
- 스레드 풀이 더 이상 절대적인 한계가 아님.
- 간단한 블로킹 코드도 대규모 동시성을 지원할 수 있음.
가상 스레드는 블로킹을 없애는 것이 아니라, 블로킹의 비용을 없애는 것입니다.
How They Differ
핵심 차이는 각 스레드 유형이 블로킹을 처리하는 방식에 있습니다:
| Aspect | Platform Thread | Virtual Thread |
|---|---|---|
| Mapping | One‑to‑one with OS thread | Many virtual threads share carrier threads |
| Blocking impact | Blocks an OS thread | Blocks only the virtual thread |
| Creation cost | High (stack, scheduling) | Low (JVM‑managed) |
| Scalability | Limited by OS resources | Can handle millions of concurrent tasks |
When It Makes Sense to Use One Over the Other
Use Virtual Threads When
- 작업이 I/O‑중심일 때(예: 많은 동시 요청 처리).
- 데이터베이스, 외부 API, 파일 시스템 등을 기다릴 때.
- 웹 서버, API, 마이크로서비스를 구축할 때.
- 단순하고 블로킹 방식의 코드를 원하면서도 확장성을 유지하고 싶을 때.
Use Platform Threads When
- 작업이 CPU‑집약적일 때.
- OS와의 긴밀한 상호작용이 필요할 때.
- 스레드 고정(pin), 네이티브 호출 또는 기타 저수준 작업이 포함될 때.
Practical Guideline
Use virtual threads for waiting; use platform threads for computing.
이 규칙은 대부분의 실제 상황에서 적용됩니다.
가상 스레드는 Java를 더 빠르게 만들지는 않지만, 스레드 풀 한계를 신경 쓰지 않고도 간단한 블로킹 코드를 쉽게 작성할 수 있게 해줍니다.