# 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 应用即可无缝切换到虚拟线程模型,以极低的代码改动成本获得高并发能力的提升。