-
Virtual Thread in JAVA개발/기술 2026. 1. 14. 11:46
작업마다 Java Thread 를 생성하면 OS 단위에서 Thread 를 생성하기 때문에 비싸고 시간도 오래 걸린다. 그래서 Java 진영에선 기존에 생성하던 Java Thread 를 Platform Thread 라고 정의하고 Virtual Thread 라는 것을 새로 만들어서 Platform Thread 위에서 실행되는 구조를 잡았다.

출처: 우아한기술블로그 (https://techblog.woowahan.com/15398/) Virtual Thread 는 Heap 메모리에 있는 객체다. Virtual 스레드는 생성 작업이 JVM 위에서 이뤄지기 때문에 Platform Thread 에 비해서 생성 비용도 싸다. Stack 이나 IP 같은 저장공간도 JVM 내에서 컨텍스트 스위칭 되는 형태이기 때문에 불필요한 시스템 콜이 없어지게 된다
Java Thread 에 비해서 커널레벨까지 내려가서 실행하는 시스템 작업이 없어 효율적이다.
추가로 Virtual Thread 의 강점은 Blocking I/O 를 Non blocking I/O 로 실행하게 된다는 점이다.
기존 Java Thread 를 사용할 경우 I/O 작업이 오래 걸리면 끝까지 기다리게 된다. 반면에 Virtual Thread 에서는 JVM 이 Blocking 을 감지하면 실행하고 있던 Virtual Thread 를 중지하고 다른 Virtual Thread 를 실행한다.
그래서 하나의 Java Thread 를 사용해도 두개의 작업을 동시에 실행하는 효과를 내게 된다.
public class TEST { private static final int TASKS = 1000; public static void main(String[] args) { long start = System.currentTimeMillis(); ioBoundTask(); System.out.printf("Time %dms\n", System.currentTimeMillis() - start); } private static void ioBoundTask() { try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 0; i < TASKS; i++) { executorService.submit(() -> { for (int j = 0; j < 100; j++) { System.out.println("Executing Blocking Task: " + Thread.currentThread()); try { Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); } } } }Virtual Thread 를 sleep 코드에서 blocking 이 발생하지 않아서 새로운 쓰레드 생성을 계속한다. 그래서 1000개의 쓰레드를 생성하는데 1233ms 만 소요된다
Executing Blocking Task: VirtualThread[#686]/runnable@ForkJoinPool-1-worker-5 Executing Blocking Task: VirtualThread[#482]/runnable@ForkJoinPool-1-worker-2 Executing Blocking Task: VirtualThread[#688]/runnable@ForkJoinPool-1-worker-2 Executing Blocking Task: VirtualThread[#635]/runnable@ForkJoinPool-1-worker-4 Executing Blocking Task: VirtualThread[#645]/runnable@ForkJoinPool-1-worker-8 Executing Blocking Task: VirtualThread[#937]/runnable@ForkJoinPool-1-worker-1 Executing Blocking Task: VirtualThread[#972]/runnable@ForkJoinPool-1-worker-6 Tasks took 1233ms to completenewCachedThreadPool 을 사용하는 경우 Java Thread 를 생성해야 하기 때문에 시간이 더 소요되고 경우에 따라선 하드웨어 자원이 부족해 crash 가 발생하게 된다.
Executing Blocking Task: Thread[#286,pool-1-thread-259,5,main] Executing Blocking Task: Thread[#1006,pool-1-thread-979,5,main] Executing Blocking Task: Thread[#286,pool-1-thread-259,5,main] Executing Blocking Task: Thread[#1006,pool-1-thread-979,5,main] Tasks took 1760ms to complete'개발 > 기술' 카테고리의 다른 글
카프카 - URP, Under Min ISR (0) 2024.08.30 Zookeeper 사용 목적과 사례 중심으로 정리 (0) 2024.08.16 VIP, HA (0) 2023.11.27 가상 스레드(Virtual Thread) 그리고 스프링 (0) 2023.11.24 single threaded vs multi threaded (0) 2023.03.16