TokyoAJ

도쿄아재

SPRINGBOOT 2025.08.27

Java Virtual Threads (가상 스레드) 완전 정리

Java 19(Preview)에서 처음 등장해 Java 21 LTS에서 정식 기능으로 자리 잡은 Virtual Threads(가상 스레드)는 자바 동시성 모델에 큰 혁신을 가져왔습니다.

수천 ~ 수백만 개의 동시 작업을 가볍게 실행할 수 있도록 설계되어, 기존 플랫폼 스레드 대비 저렴한 생성 비용과 간단한 동시성 코드 작성을 가능하게 합니다.


Virtual Threads의 필요성

  1. 기존 Thread는 운영체제(OS) 스레드와 1:1 매핑 → 많은 수의 동시 요청 처리에 한계.
  2. Virtual Threads는 JVM 내부에서 관리하는 경량 스레드 → 수십만 개도 무리 없이 실행.
  3. 비동기/논블로킹 API를 억지로 쓰지 않고도 블로킹 스타일 코드 그대로 고성능을 낼 수 있습니다.


1. 가장 간단한 Virtual Thread 예제

public class VirtualThreadExample {
public static void main(String[] args) throws InterruptedException {
Thread vt = Thread.ofVirtual().start(() -> {
System.out.println("Hello from a virtual thread!");
});
vt.join();
}
}

Thread.ofVirtual().start(...) 만으로 Virtual Thread 실행.

join()으로 main 스레드가 해당 Virtual Thread 종료까지 대기.


2. Virtual Threads 여러 개 실행하기

import java.util.concurrent.*;

public class VirtualThreadExecutor {
public static void main(String[] args) throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 5; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " running on " + Thread.currentThread());
Thread.sleep(100); // 블로킹 호출도 저렴하게 처리
return taskId;
});
}
}
}
}

Executors.newVirtualThreadPerTaskExecutor() 를 사용하면 작업마다 Virtual Thread 생성.

수천, 수백만 개의 요청도 저비용으로 처리 가능.


3. Virtual Threads와 HTTP 요청 병렬 처리

import java.net.http.*;
import java.net.URI;
import java.util.concurrent.*;

public class HttpClientWithVirtualThreads {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();

try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
var urls = new String[] {
"https://example.com",
"https://openjdk.org",
"https://docs.oracle.com"
};

for (String url : urls) {
executor.submit(() -> {
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(url))
.build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("Fetched " + url + " length=" + resp.body().length());
});
}
}
}
}

기존 HTTP Client API와 동일하게 작성하되, Virtual Threads 덕분에 블로킹 방식으로도 효율적인 동시 요청 처리.


4. 더욱 간략한 예제 (추천 블로그용)

public class SimpleVT {
public static void main(String[] args) {
Thread.startVirtualThread(() -> System.out.println("Hello, Virtual Thread!"));
}
}

Thread.startVirtualThread(...) 를 쓰면 한 줄로 Virtual Thread 생성 가능.

간단한 예제로 블로그/발표자료에 적합.


마무리

  1. Java 21 LTS부터 Virtual Threads는 안정적으로 사용 가능.
  2. 기존 동시성 코드(Thread, ExecutorService)와 API가 동일해 학습 비용이 낮음.
  3. Spring, Netty 등 서버 프레임워크와도 점차 통합/지원 확대 중.


실무 팁:

  1. 대규모 I/O 바운드 서비스(웹 서버, 메시징, DB 클라이언트)에 가장 효과적.
  2. CPU 바운드 작업은 기존 플랫폼 스레드와 차이 없음.
  3. Virtual Thread와 Structured Concurrency(JEP 428) 조합으로 더 안전한 동시성 코드 작성 가능.


댓글