虚拟线程在SpringBoot中的应用

什么是虚拟线程虚拟线程是JAVA19开始增加的一个特性,和Golang的携程类似,一个其它语言早就提供的、且如此实用且好用的功能,作为一个Java开发者,早就已经望眼欲穿了 。
虚拟线程和普通线程的区别“虚拟”线程,望文生义,它是“假”的,它不直接调度操作系统的线程,而是由JVM再提供一层线程的接口抽象,由普通线程调度,即一个普通的操作系统线程可以调度成千上万个虚拟线程 。虚拟线程比普通线程的消耗要小得多得多,在内存足够的情况下,我们甚至可以创建上百万的虚拟线程,这在之前(Java19以前)是不可能的 。

其实如果有用过akka的朋友们会发现,其实两者很相似,只不过使用akka是应用程序来处理,而虚拟线程是JVM来处理,使用上更简洁且方便 。
SpringBoot使用虚拟线程下面我们会在SpringBoot中使用虚拟线程,将默认的异步线程池和http处理线程池替换为虚拟线程,然后对比虚拟线程和普通线程的性能差异,你会发现差别就像马车换高铁,不是一个时代的东西 。
配置首先我们使用的Java版本是java-20.0.2-oracle,SpringBoot版本是3.1.2 。
要在SpringBoot中使用虚拟线程很简单,增加如下配置即可:
java复制代码/** * 配置是用于稍后测试,spring.virtual-thread=true是使用虚拟线程,false时还是使用默认的普通线程 */@Configuration@ConditionalOnProperty(prefix = "spring", name = "virtual-thread", havingValue = https://www.isolves.com/it/cxkf/kj/2023-08-16/"true")public class ThreadConfig {@Beanpublic AsyncTaskExecutor ApplicationTaskExecutor() {return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());}@Beanpublic TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() {return protocolHandler -> {protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());};}}@Async性能对比我们写一个异步service,里面睡眠50ms,模拟MySQL或redis等IO操作:
java复制代码@Servicepublic class AsyncService {/**** @param countDownLatch 用于测试*/@Asyncpublic void doSomething(CountDownLatch countDownLatch) throws InterruptedException {Thread.sleep(50);countDownLatch.countDown();}}最后测试类,很简单,就是循环调用这个方法10万次,计算所有方法执行完成的消耗的时间:
java复制代码@Testpublic void testAsync() throws InterruptedException {long start = System.currentTimeMillis();int n = 1000;CountDownLatch countDownLatch = new CountDownLatch(n);for (int i = 0; i < n; i++) {asyncService.doSomething(countDownLatch);}countDownLatch.awAIt();long end = System.currentTimeMillis();System.out.println("耗时:" + (end - start) + "ms");}


    推荐阅读