SpringBoot3中使用虚拟线程的完整步骤

 更新时间:2025年06月08日 15:41:27   作者:酷爱码  
在 Spring Boot 3 中使用 Java 21+ 的虚拟线程(Virtual Threads)可以显著提升 I/O 密集型应用的并发能力,这篇文章为大家介绍了详细的实现步骤,希望对大家有所帮助

1. 环境准备

JDK 21+:确保安装 JDK 21 或更高版本

Spring Boot 3.2+:最低要求(pom.xml 或 build.gradle)

<!-- Maven 依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version> <!-- 或更高版本 -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
// Gradle 依赖
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

2. 配置虚拟线程

方式一:全局启用虚拟线程(Tomcat/Jetty)

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 {

    // Tomcat 配置(默认服务器)
    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
        return protocolHandler -> 
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
    }

    // Jetty 配置(如使用Jetty)
    // @Bean
    // public JettyVirtualThreadsCustomizer jettyVirtualThreadsCustomizer() {
    //    return new JettyVirtualThreadsCustomizer();
    // }
}

方式二:异步任务使用虚拟线程

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "virtualThreadExecutor")
    public Executor virtualThreadExecutor() {
        return Thread.ofVirtual().name("virtual-", 0).factory()::newThread;
    }
}

使用异步方法:

@Service
public class AsyncService {

    @Async("virtualThreadExecutor")  // 指定执行器
    public CompletableFuture<String> asyncTask() {
        // 模拟耗时I/O操作
        return CompletableFuture.completedFuture("Virtual thread task completed");
    }
}

3. 验证虚拟线程

测试控制器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;

@RestController
public class TestController {

    @GetMapping("/thread")
    public String getThreadType() {
        // 打印当前线程信息
        Thread thread = Thread.currentThread();
        return """
            Thread name: %s
            Is virtual: %s
            Platform thread: %s
            """.formatted(
                thread.getName(),
                thread.isVirtual(),
                thread.isVirtual() ? "N/A" : thread.toString()
            );
    }

    @GetMapping("/sleep")
    public CompletableFuture<String> sleep() throws InterruptedException {
        Thread.sleep(1000); // 模拟I/O阻塞
        return CompletableFuture.completedFuture(
            "Done by: " + Thread.currentThread().getName()
        );
    }
}

4. 启动应用

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

5. 测试验证

1.访问 http://localhost:8080/thread 查看线程类型:

Thread name: virtual-0
Is virtual: true
Platform thread: N/A

2.并发测试(使用 ab 或 JMeter):

ab -n 1000 -c 200 http://localhost:8080/sleep

观察低内存占用和高吞吐量

6.关键注意事项

阻塞操作识别:

  • 虚拟线程在 synchronized 块或本地方法调用时会固定到平台线程
  • 使用 jcmd <PID> Thread.dump_to_file -format=json <file> 分析线程状态

线程局部变量:

  • 虚拟线程支持 ThreadLocal,但避免滥用(可能增加内存压力)
  • 考虑使用 ScopedValue(Java 21+)

数据库连接池:

// application.properties
spring.datasource.hikari.thread-factory=java.util.concurrent.ThreadFactory

调试配置:

java -Djdk.tracePinnedThreads=full -jar your-app.jar

7.完整配置示例(Tomcat + HikariCP)

@Configuration
public class VirtualThreadGlobalConfig {

    // Tomcat 虚拟线程执行器
    @Bean
    TomcatProtocolHandlerCustomizer<?> tomcatVirtualThreads() {
        return handler -> handler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
    }

    // HikariCP 使用虚拟线程工厂
    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public HikariDataSource dataSource() {
        return new HikariDataSource(new HikariConfig() {{
            setThreadFactory(Thread.ofVirtual().factory());
        }});
    }

    // 异步任务执行器
    @Bean
    Executor virtualThreadExecutor() {
        return Executors.newVirtualThreadPerTaskExecutor();
    }
}

重要提示:虚拟线程最适合 I/O 密集型场景(如网络请求、数据库调用),对计算密集型任务提升有限。生产环境务必进行压力测试!

到此这篇关于SpringBoot3中使用虚拟线程的完整步骤的文章就介绍到这了,更多相关SpringBoot3使用虚拟线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springcloud中的@RefreshScope的实现

    Springcloud中的@RefreshScope的实现

    @RefreshScope注解是Spring Cloud中的一个注解,它用来实现Bean中属性的动态刷新,本文就来介绍一下@RefreshScope注解的使用,感兴趣的可以了解一下
    2024-06-06
  • 最全MyBatis核心配置文件总结(收藏)

    最全MyBatis核心配置文件总结(收藏)

    这篇文章主要介绍了最全MyBatis核心配置文件总结(收藏),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java Druid连接池与Apache的DBUtils使用教程

    Java Druid连接池与Apache的DBUtils使用教程

    这篇文章主要介绍了Java Druid连接池与Apache的DBUtils使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-12-12
  • Java弱键集合WeakHashMap及ConcurrentCache原理详解

    Java弱键集合WeakHashMap及ConcurrentCache原理详解

    这篇文章主要介绍了Java弱键集合WeakHashMap及ConcurrentCache原理详解,基于哈希表的Map接口实现,支持null键和值,但是WeakHashMap具有弱键,可用来实现缓存存储,在进行GC的时候会自动回收键值对,需要的朋友可以参考下
    2023-09-09
  • java 获取路径的各种方法(总结)

    java 获取路径的各种方法(总结)

    下面小编就为大家带来一篇java 获取路径的各种方法(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • 详解mybatis中association和collection的column传入多个参数问题

    详解mybatis中association和collection的column传入多个参数问题

    这篇文章主要介绍了详解mybatis中association和collection的column传入多个参数问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Java通过jedis连接redis的几种常用方法

    Java通过jedis连接redis的几种常用方法

    jedis封装了redis原有的操作命令,使用起来很简单,本文主要介绍了Java通过jedis连接redis的几种常用方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • mybatis自定义参数类型转换器数据库字段加密脱敏

    mybatis自定义参数类型转换器数据库字段加密脱敏

    这篇文章主要为大家介绍了mybatis自定义参数类型转换器数据库字段加密脱敏,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 使用springmvc参数接收boolean类型参数的问题

    使用springmvc参数接收boolean类型参数的问题

    这篇文章主要介绍了使用springmvc参数接收boolean类型参数的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Springboot整合Druid实现对访问的监控方式

    Springboot整合Druid实现对访问的监控方式

    这篇文章主要介绍了Springboot整合Druid实现对访问的监控方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05

最新评论