Java虚拟线程

什么是虚拟线程

虚拟线程(Virtual Thread)是JDK 21引入的轻量级线程,由JVM调度而非操作系统。

为什么需要虚拟线程

特性

平台线程

虚拟线程

创建成本

高(~1MB栈)

低(~1KB)

数量上限

数千

数百万

调度

OS内核

JVM

阻塞代价

占用OS线程

自动让出

适合IO密集型:大量等待时,虚拟线程不占用OS线程资源。

不适合CPU密集型:计算时不让出,与平台线程无异。

对比平台线程

平台线程(传统):

// 创建10000个线程可能OOM
for (int i = 0; i < 10000; i++) {
    new Thread(() -> {
        try { Thread.sleep(1000); } catch (Exception e) {}
    }).start();
}

虚拟线程

// 创建100万个虚拟线程没问题
for (int i = 0; i < 1_000_000; i++) {
    Thread.ofVirtual().start(() -> {
        try { Thread.sleep(1000); } catch (Exception e) {}
    });
}

如何使用

JDK 21+:

// 方式1:直接创建
Thread vthread = Thread.ofVirtual().start(() -> {
    System.out.println("Hello from virtual thread");
});

// 方式2:ExecutorService
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 10000; i++) {
        executor.submit(() -> {
            // IO操作会自动让出虚拟线程
            return fetchFromDB();
        });
    }
}

类似async/await

Python/Rust的async/await

  • 显式声明异步函数

  • 需要用 await 标记等待点

  • 代码有"传染性"(函数签名要改)

  • 精确控制挂起点

Java虚拟线程

  • 无需修改代码,同步写法

  • JVM自动在阻塞时挂起

  • 对现有代码透明

  • 无法精确控制挂起点

本质相同:都是用户态轻量级并发,只是实现和语法风格不同。

关键点

  • JDK 21正式引入

  • 阻塞IO操作自动让出载体线程

  • 不要池化虚拟线程

  • ThreadLocal使用需谨慎

  • 适合高并发IO场景