Java 19(Preview)에서 처음 등장해 Java 21 LTS에서 정식 기능으로 자리 잡은 Virtual Threads(가상 스레드)는 자바 동시성 모델에 큰 혁신을 가져왔습니다.
수천 ~ 수백만 개의 동시 작업을 가볍게 실행할 수 있도록 설계되어, 기존 플랫폼 스레드 대비 저렴한 생성 비용과 간단한 동시성 코드 작성을 가능하게 합니다.
Virtual Threads의 필요성
- 기존
Thread
는 운영체제(OS) 스레드와 1:1 매핑 → 많은 수의 동시 요청 처리에 한계. - Virtual Threads는 JVM 내부에서 관리하는 경량 스레드 → 수십만 개도 무리 없이 실행.
- 비동기/논블로킹 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 생성 가능.
간단한 예제로 블로그/발표자료에 적합.
마무리
- Java 21 LTS부터 Virtual Threads는 안정적으로 사용 가능.
- 기존 동시성 코드(
Thread
, ExecutorService
)와 API가 동일해 학습 비용이 낮음. - Spring, Netty 등 서버 프레임워크와도 점차 통합/지원 확대 중.
실무 팁:
- 대규모 I/O 바운드 서비스(웹 서버, 메시징, DB 클라이언트)에 가장 효과적.
- CPU 바운드 작업은 기존 플랫폼 스레드와 차이 없음.
- Virtual Thread와 Structured Concurrency(JEP 428) 조합으로 더 안전한 동시성 코드 작성 가능.
댓글