# virtual-thread
**Repository Path**: nikai/virtual-thread
## Basic Information
- **Project Name**: virtual-thread
- **Description**: Spring MVC + Java虚拟线程
优势:无需学习响应式编程范式,代码编写、调试门槛低,天然规避WebFlux搭配阻塞JDBC的线程陷阱,直接调用普通JDBC即可获得接近WebFlux的高并发吞吐量。
适用场景:团队熟悉Spring生态、项目依赖大量阻塞式API,不想投入响应式学习成本的场景。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-12
- **Last Updated**: 2026-08-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# JVM虚拟线程
在 Spring Boot 3.2+ 和 JDK 21+ 环境下,配置 Spring MVC 使用虚拟线程(Virtual Threads)非常简单。核心目标是让 Tomcat(或其他嵌入式容器)使用虚拟线程来处理 HTTP 请求,从而以极低的资源消耗实现高并发。
以下是完整的配置步骤、代码示例及关键注意事项:
一、环境准备
JDK 版本:必须使用 JDK 21 或更高版本。
Spring Boot 版本:建议使用 Spring Boot 3.2.0 或更高版本(原生支持虚拟线程配置)。
二、核心配置方法(推荐)
最简单且官方推荐的方式是通过 application.yml 或 `application.properties进行全局启用。
1. 修改配置文件
在 src/main/resources/application.yml 中添加以下配置:
yaml
spring:
threads:
virtual:
enabled: true # 一键启用虚拟线程
或者在 application.properties 中:
properties
spring.threads.virtual.enabled=true
效果:
Spring Boot 会自动配置 Tomcat 的 ProtocolHandler,使其使用 Executors.newVirtualThreadPerTaskExecutor()。
所有进入 Spring MVC Controller 的请求将在虚拟线程中执行。
@Async 异步方法默认也会使用虚拟线程执行器(如果未自定义其他 Executor)。
2. Maven/Gradle 配置确认
确保编译器目标版本为 21:
Maven (pom.xml):
xml
21
org.springframework.boot
spring-boot-starter-parent
3.2.5
Gradle (build.gradle):
groovy
java {
sourceCompatibility = '21'
targetCompatibility = '21'
}
三、验证配置是否生效
编写一个简单的 Controller 来检查当前线程类型:
java
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class VirtualThreadCheckController {
@GetMapping("/check-thread")
public String checkThread() {
Thread currentThread = Thread.currentThread();
boolean isVirtual = currentThread.isVirtual();
return String.format("Thread Name: %s, Is Virtual: %b",
currentThread.getName(), isVirtual);
}
}
预期结果:
访问 http://localhost:8080/check-thread,返回内容中 Is Virtual 应为 true,且线程名通常包含 virt 字样(如 virt-1)。
四、进阶配置(可选)
如果你需要更细粒度的控制,或者使用的是非 Tomcat 容器(如 Jetty),可以通过 Java Config 方式手动配置。
1. 自定义 Tomcat 执行器
虽然 spring.threads.virtual.enabled=true 已经足够,但你也可以显式配置 Tomcat:
java
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
@Configuration
public class VirtualThreadConfig {
@Bean
public TomcatProtocolHandlerCustomizer> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> {
// 为每个任务创建一个虚拟线程
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
};
}
}
2. 配置 @Async 使用虚拟线程
如果启用了全局虚拟线程,@Async 默认会使用虚拟线程。若需显式指定或自定义:
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "virtualTaskExecutor")
public Executor virtualTaskExecutor() {
return Executors.newVirtualThreadPerTaskExecutor();
}
}
在使用时指定执行器名称:
java
@Service
public class AsyncService {
@Async("virtualTaskExecutor")
public CompletableFuture doAsyncWork() {
// 业务逻辑
return CompletableFuture.completedFuture("Done");
}
}
五、关键注意事项与避坑指南
适用场景:
适合:I/O 密集型应用(如调用数据库、Redis、远程 HTTP API、文件读写)。虚拟线程在阻塞 I/O 时会“卸载”(unmount),释放底层平台线程去处理其他任务,从而极大提升吞吐量。
不适合:CPU 密集型任务(如复杂计算、视频编码)。虚拟线程不会提升 CPU 计算速度,反而可能因调度开销略低于平台线程。
线程局部变量(ThreadLocal):
虚拟线程支持 ThreadLocal,但由于虚拟线程数量可能极大(百万级),频繁创建大量 ThreadLocal 可能导致内存问题。建议谨慎使用,或考虑使用 ScopedValue(Java 21 预览特性)作为替代。
同步块(synchronized):
在虚拟线程中使用 synchronized 是安全的,但会导致虚拟线程“ pinned ”(钉住),即阻塞时不会卸载,会占用底层平台线程。
建议:尽量使用 ReentrantLock 或其他 java.util.concurrent 锁机制,它们能更好地与虚拟线程协作。
数据库连接池:
虚拟线程本身不解决数据库连接瓶颈。如果并发量极大,需确保数据库连接池(如 HikariCP)的大小足够,或考虑使用响应式数据库驱动(如 R2DBC)以彻底消除阻塞。但通常对于大多数应用,适当调大连接池配合虚拟线程即可显著提升性能。
调试与监控:
虚拟线程栈追踪可能与传统线程不同。使用 JDK 21 提供的 jcmd 或新的 Flight Recorder 事件可以更好地监控虚拟线程行为。
通过以上配置,你的 Spring MVC 应用即可无缝切换到虚拟线程模型,以极低的代码改动成本获得高并发能力的提升。