SpringBoot3中使用虛擬線程的完整步驟
1. 環(huán)境準(zhǔn)備
JDK 21+:確保安裝 JDK 21 或更高版本
Spring Boot 3.2+:最低要求(pom.xml 或 build.gradle)
<!-- Maven 依賴(lài) -->
<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 依賴(lài)
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 配置(默認(rèn)服務(wù)器)
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler ->
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
}
// Jetty 配置(如使用Jetty)
// @Bean
// public JettyVirtualThreadsCustomizer jettyVirtualThreadsCustomizer() {
// return new JettyVirtualThreadsCustomizer();
// }
}
方式二:異步任務(wù)使用虛擬線程
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") // 指定執(zhí)行器
public CompletableFuture<String> asyncTask() {
// 模擬耗時(shí)I/O操作
return CompletableFuture.completedFuture("Virtual thread task completed");
}
}
3. 驗(yàn)證虛擬線程
測(cè)試控制器
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() {
// 打印當(dāng)前線程信息
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. 啟動(dòng)應(yīng)用
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
5. 測(cè)試驗(yàn)證
1.訪問(wèn) http://localhost:8080/thread 查看線程類(lèi)型:
Thread name: virtual-0
Is virtual: true
Platform thread: N/A
2.并發(fā)測(cè)試(使用 ab 或 JMeter):
ab -n 1000 -c 200 http://localhost:8080/sleep
觀察低內(nèi)存占用和高吞吐量
6.關(guān)鍵注意事項(xiàng)
阻塞操作識(shí)別:
- 虛擬線程在 synchronized 塊或本地方法調(diào)用時(shí)會(huì)固定到平臺(tái)線程
- 使用 jcmd <PID> Thread.dump_to_file -format=json <file> 分析線程狀態(tài)
線程局部變量:
- 虛擬線程支持 ThreadLocal,但避免濫用(可能增加內(nèi)存壓力)
- 考慮使用 ScopedValue(Java 21+)
數(shù)據(jù)庫(kù)連接池:
// application.properties spring.datasource.hikari.thread-factory=java.util.concurrent.ThreadFactory
調(diào)試配置:
java -Djdk.tracePinnedThreads=full -jar your-app.jar
7.完整配置示例(Tomcat + HikariCP)
@Configuration
public class VirtualThreadGlobalConfig {
// Tomcat 虛擬線程執(zhí)行器
@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());
}});
}
// 異步任務(wù)執(zhí)行器
@Bean
Executor virtualThreadExecutor() {
return Executors.newVirtualThreadPerTaskExecutor();
}
}
重要提示:虛擬線程最適合 I/O 密集型場(chǎng)景(如網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)調(diào)用),對(duì)計(jì)算密集型任務(wù)提升有限。生產(chǎn)環(huán)境務(wù)必進(jìn)行壓力測(cè)試!
到此這篇關(guān)于SpringBoot3中使用虛擬線程的完整步驟的文章就介紹到這了,更多相關(guān)SpringBoot3使用虛擬線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Java堆內(nèi)存的10個(gè)要點(diǎn)的總結(jié)分析
本篇文章是對(duì)Java堆內(nèi)存的10個(gè)要點(diǎn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Java動(dòng)態(tài)代理機(jī)制詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)代理機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
SpringBoot集成MinIO實(shí)現(xiàn)高效文件存儲(chǔ)的實(shí)戰(zhàn)方案
在后端開(kāi)發(fā)中,文件存儲(chǔ)是高頻需求,傳統(tǒng)本地存儲(chǔ)存在擴(kuò)展性差、集群部署不便、數(shù)據(jù)易丟失等問(wèn)題,MinIO作為開(kāi)源高性能對(duì)象存儲(chǔ)服務(wù),可輕松實(shí)現(xiàn)文件的上傳、下載、預(yù)覽、刪除等功能,本文聚焦SpringBoot與MinIO的實(shí)戰(zhàn)落地,實(shí)現(xiàn)高效文件管理,需要的朋友可以參考下2026-01-01
Java中Stream?Filter多條件篩選過(guò)濾代碼舉例
這篇文章主要給大家介紹了關(guān)于Java中Stream?Filter多條件篩選過(guò)濾的相關(guān)資料,Java Stream中的filter方法可以使用多個(gè)條件來(lái)過(guò)濾數(shù)據(jù),文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2023-12-12
一文教會(huì)你如何搭建vue+springboot項(xiàng)目
最近在搗鼓?SpringBoot?與?Vue?整合的項(xiàng)目,所以下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章教會(huì)你搭建vue+springboot項(xiàng)目,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
JAVA求兩直線交點(diǎn)和三角形內(nèi)外心的方法
本文提供了JAVA求兩直線交點(diǎn)、三角形外心、三角形內(nèi)心的代碼和算法講解,大家可以參考使用2013-11-11
java轉(zhuǎn)換時(shí)區(qū)時(shí)間過(guò)程詳解
這篇文章主要介紹了java轉(zhuǎn)換時(shí)區(qū)時(shí)間過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
springBoot使用openfeign來(lái)遠(yuǎn)程調(diào)用的實(shí)現(xiàn)
這篇文章主要介紹了springBoot使用openfeign來(lái)遠(yuǎn)程調(diào)用的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

