Spring Boot 3.2+ 正式支持虚拟线程,只需几行配置,Tomcat/Jetty/Undertow、@Async、TaskScheduler 全部自动适配


1. 环境要求

  • JDK 21 / 22
  • Spring Boot 3.2.0+
  • 推荐使用默认的 Tomcat

2. pom.xml(Maven)

xml

<properties>
    <java.version>22</java.version>
    <spring-boot.version>3.2.5</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>

Gradle 同理,确保 Java 版本为 22,Spring Boot ≥3.2。


3. application.yml 核心配置(开启虚拟线程)

yaml

spring:
  threads:
    virtual:
      enabled: true  # 🔥 核心开关:开启虚拟线程

  # 异步任务也用虚拟线程(@Async)
  task:
    execution:
      thread-name-prefix: async-vt-

server:
  tomcat:
    # 虚拟线程下,connection 可以设大一点
    max-connections: 10000
    accept-count: 1000

只需要这一个 enabled: true,整个 Web 容器就切换到虚拟线程了。


4. 启动类(开启异步)

如果你要用 @Async,记得加 @EnableAsync

java

运行

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync  // 开启异步
public class VirtualThreadApplication {
    public static void main(String[] args) {
        SpringApplication.run(VirtualThreadApplication.class, args);
    }
}

5. 测试接口(验证是否为虚拟线程)

java

运行

import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/test")
    public String test() {
        Thread thread = Thread.currentThread();
        return "线程名称: " + thread.getName()
                + "\n是否虚拟线程: " + thread.isVirtual();
    }

    @Async
    @GetMapping("/async")
    public String async() {
        Thread thread = Thread.currentThread();
        return "异步线程名称: " + thread.getName()
                + "\n是否虚拟线程: " + thread.isVirtual();
    }
}

访问后会返回:

plaintext

是否虚拟线程: true

6. 高级配置:自定义虚拟线程工厂

如果你想自定义线程名称、异常处理器,可以手动注册 VirtualThreadTaskExecutor

java

运行

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
public class VirtualThreadConfig {

    // Web 异步 & @Async 使用虚拟线程
    @Bean
    public VirtualThreadTaskExecutor applicationTaskExecutor() {
        return new VirtualThreadTaskExecutor("vt-");
    }

    // 如果你需要兼容旧代码,也可以混合使用
    // @Bean
    // public ThreadPoolTaskExecutor platformTaskExecutor() {
    //     ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    //     executor.setCorePoolSize(20);
    //     executor.setMaxPoolSize(50);
    //     return executor;
    // }
}

7. 启动时看到的关键日志

成功开启虚拟线程后,启动日志会出现:

plaintext

Using virtual threads for web handling
Using VirtualThreadTaskExecutor

8. 压测表现(简单对比)

  • 传统 Tomcat 线程池:200 线程 撑死 200 并发
  • 虚拟线程:几万、几十万并发 轻松跑,内存几乎不涨
  • 适合:API 接口、网关、IO 密集型服务

9. 注意事项(非常重要)

  1. 不要在虚拟线程里写死循环 / 重度 CPU 计算会霸占载体线程,导致整个虚拟线程调度性能下降。

  2. 长耗时 synchronized 要避免会导致虚拟线程 Pinning(钉在载体线程无法切换),建议用 ReentrantLock

  3. 不要池化虚拟线程Spring 已经自动做到 “来一个请求开一个虚拟线程”,这是最优模式。

  4. ThreadLocal 可以用,但不要存大对象每个虚拟线程都有独立 ThreadLocal,存大对象会吃内存。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐