springboot3 + java虚拟线程初体验

java虚拟线程介绍

虚拟线程是 Java 19 的 预览特性,估计会在Java 21被纳入 JDK 的正式版本中,会在2023年9月发布,目前springboot 3 已经提供了对虚拟线程的支持。

虚拟线程和平台线程主要区别在于,虚拟线程在运行周期内不依赖操作系统线程:它们与硬件脱钩,因此被称为 "虚拟"。这种解耦是由 JVM 提供的抽象层赋予的。

虚拟线程的运行成本远低于平台线程。消耗的内存要少得多。这就是为什么可以创建数百万个虚拟线程而不会出现内存不足的问题,而标准平台(或内核)线程只能创建数百个。

从理论上讲,这赋予了开发人员一种超级能力:无需依赖异步代码即可实现高性能的应用程序。

预计在不久的未来,常见的开源框架(Tomcat、Spring、Netty)都会基于虚拟线程推出新版本。

环境准备

java 20:下载地址:OpenJDK JDK 20.0.2 GA Release

idea社区版2023.2版本,目前最高支持到java 20,下载地址:下载 IntelliJ IDEA -- 领先的 Java 和 Kotlin IDE

新建springboot3项目

https://start.spring.io/

在idea打开项目,最终项目文件如下图。修改项目设置:

项目文件

POM文件:修改后一定要执行一次:Maven--reload project

XML 复制代码
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>20</source>
					<target>20</target>
					<compilerArgs>
						<arg>--enable-preview</arg>
					</compilerArgs>
				</configuration>
			</plugin>

springboot启动文件

java 复制代码
@SpringBootApplication
@EnableAsync
public class VttestApplication {

	public static void main(String[] args) {
		SpringApplication.run(VttestApplication.class, args);
	}
}
复制代码
ThreadConfig.java
java 复制代码
@Configuration
@ConditionalOnProperty(value = "spring.thread-executor", havingValue = "virtual")
public class ThreadConfig {

    @Bean
    public AsyncTaskExecutor applicationTaskExecutor() {
        return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
    }

    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
        return protocolHandler -> {
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        };
    }
}
复制代码
AsyncService.java
java 复制代码
@Service
public class AsyncService {
    private static final Log log = LogFactory.getLog(AsyncService.class);
    /**
     *
     * @param countDownLatch 用于测试
     */
    @Async
    public void doSomething(CountDownLatch countDownLatch) {
//        log.info(Thread.currentThread());
        try {
            Thread.sleep(50);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        countDownLatch.countDown();
    }
}
复制代码
TestController.java
java 复制代码
@RestController
@RequestMapping("/test")
public class TestController {

    private static final Log log = LogFactory.getLog(TestController.class);

    @Autowired
    AsyncService asyncService;

    @GetMapping("/vt")
    public String vt() {
        long start = System.currentTimeMillis();
        int n = 10000;
        CountDownLatch countDownLatch = new CountDownLatch(n);
        for (int i = 0; i < n; i++) {
            asyncService.doSomething(countDownLatch);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }

        long end = System.currentTimeMillis();
        log.info("耗时:" + (end - start) + "ms");
        return "OK";
    }

    @GetMapping("/ds")
    public void doSomething() throws InterruptedException {
//        log.info("hey, I'm doing something");
        Thread.sleep(1000);
    }

}

application.yml

java 复制代码
server:
  port: 8092
  #开启优雅停机,默认immediate是立即关机
  shutdown: graceful
  tomcat.threads.max: ${TOMCAT_THREAD_NUM:800}


logging:
  level:
    com:
      demo:
        springboottest: DEBUG
#    ROOT: debug

spring:
  thread-executor: virtual  #启动虚拟线程的必须配置
  lifecycle:
    timeout-per-shutdown-phase: 30s #设置优雅停机缓冲期,最大等待时间

关键是:thread-executor: virtual #启动虚拟线程的必须配置

注释掉该行则使用普通线程,后面对比虚拟线程与普通线程性能时,可通过注释该行切换到普通线程

运行项目

通过接口 http://127.0.0.1:8092/test/vt 验证两种线程执行效率

虚拟线程执行时间:

普通线程执行时间:

这段代码执行时间相差1000倍

使用Jmeter压测 http://127.0.0.1:8092/test/ds 接口,吞吐量、响应时间均有大幅优化,并发数越高优化幅度越大。并发2000情况下的结果如下

虚拟线程

普通线程

参考文章:

在 Spring 6 中使用虚拟线程(Virtual Threads) - spring 中文网

相关推荐
JavaGuide24 天前
深信服后端开发岗校招面经,挂在了二面!
分布式·哈希算法·线程池·代码规范·分布式id·系统设计·虚拟线程·加密算法·rdb·密码加密·guice
小江的学习日记4 个月前
一文揭开JDK21虚拟线程的神秘面纱
java·多线程·虚拟线程·jep444
russle7 个月前
升级程序到Java21的记录二(修改程序源代码)
java·虚拟线程
北漂的菜小白1 年前
Spring Boot 3.2.0 Tomcat虚拟线程初体验 (部分装配解析)
java·spring boot·虚拟线程
JavaGuide1 年前
JDK21的虚拟线程是什么?和平台线程什么关系?
java·多线程·虚拟线程·javaguide
京东云技术团队1 年前
Java21上手体验-分代ZGC和虚拟线程
java·虚拟线程
京东云开发者1 年前
聊聊JDK19特性之虚拟线程
java·jdk·虚拟线程
bokerr1 年前
千呼万唤始出来 JDK 21 LTS, 久等了
协程·虚拟线程·jdk21