Java 21 虚拟线程压测全记录与性能分析
Java 21 正式引入虚拟线程(Virtual Threads),作为 Project Loom 的核心成果,彻底改变了传统线程模型在高并发场景下的资源消耗瓶颈。虚拟线程由 JVM 管理,轻量级且可瞬时创建,使得单机支撑百万级并发成为可能。
测试环境与配置
本次测试基于以下环境:
- JDK 版本:OpenJDK 21.0.2
- 硬件配置:16 核 CPU、32GB 内存、Ubuntu 22.04 LTS
- 压测工具:Apache JMeter,并发用户数设定为 10,000
- 目标接口:返回简单 JSON 响应的 Spring Boot 3.2 Web 应用
启用虚拟线程的代码实现
在 Spring Boot 中启用虚拟线程仅需一行配置:
@Bean
public TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() {
return protocolHandler -> protocolHandler.setExecutor(
Executors.newVirtualThreadPerTaskExecutor()
);
}
上述代码将 Tomcat 的请求处理线程切换为虚拟线程,每个请求由独立的虚拟线程处理,无需阻塞操作系统线程。
核心机制解析
虚拟线程的诞生背景
在高并发应用场景日益增长的今天,传统平台线程(Platform Thread)模型逐渐暴露出其性能瓶颈。JVM 中的平台线程直接映射到操作系统线程,创建和销毁成本高昂,且默认栈大小较大(通常为 1MB),导致内存资源迅速耗尽。
一个典型的服务端应用若需支持十万级并发连接,使用传统线程模型将需要同等数量的线程,这在物理内存和上下文切换开销上是不可承受的。
工作原理与调度
虚拟线程是 Project Loom 引入的核心特性,由 JVM 直接调度,无需绑定操作系统线程。它们以极低的内存开销实现高并发,每个虚拟线程仅占用几 KB 堆栈空间。
轻量级调度机制
虚拟线程由 JVM 在用户态调度,运行于少量平台线程(载体线程)之上。当虚拟线程阻塞时,JVM 自动挂起并移交载体线程执行其他任务。
Thread.ofVirtual().start(() -> {
System.out.println("运行在虚拟线程中");
});
该代码创建并启动一个虚拟线程。Thread.ofVirtual() 返回虚拟线程构建器,其 start() 方法提交任务至虚拟线程调度器,由 ForkJoinPool 统一管理执行。
与传统线程对比
| 特性 | 虚拟线程 | 平台线程 |
|---|---|---|
| 内存占用 | 约 1KB | 约 1MB |
| 创建速度 | 极快 | 较慢 |
| 最大数量 | 百万级 | 数千级 |
调度优化与 Continuation 机制
现代调度器在高并发场景下面临任务切换开销大的挑战。为提升效率,引入 Continuation 机制成为关键优化手段。该机制将异步操作的后续逻辑封装为可恢复的执行单元,避免线程阻塞。
Continuation 机制工作流程
- 任务挂起时保存上下文状态

