尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java虚拟线程(四)
SpringBoot3.2 全局开启虚拟线程后业务代码使用虚拟线程处理业务前置spring.threads.virtual.enabledtrue这个配置只作用于 Web 容器Tomcat/JettyHTTP 请求进来由虚拟线程处理 Controller。⚠️重要它不会自动把你业务里异步任务变成虚拟线程全局开启只是 Web 请求线程是 VT你自己代码里手动Async、线程池默认仍然是平台线程需要单独处理。两种场景分开1. 同步业务逻辑Controller 里直接写请求本身跑在虚拟线程上业务代码天然就在虚拟线程执行无需额外编码。RestController public class OrderController { GetMapping(/order/get) public String getOrder() { // 当前线程就是虚拟线程 Thread t Thread.currentThread(); System.out.println(isVirtual: t.isVirtual()); // DB查询、RPC调用直接写跑在Web虚拟线程 orderService.query(); remoteService.call(); return success; } }✅ 特点不需要创建任何 Executor整个请求链路都在虚拟线程。注意Controller 内同步调用属于 Web VT 的主线程IO 阻塞会释放载体线程享受虚拟线程优势。2. 业务异步任务需要新开线程执行如 Async、后台任务全局开启 Web 虚拟线程不会改造 Async 默认线程池。SpringAsync默认使用SimpleAsyncTaskExecutor平台线程想要异步任务也使用虚拟线程需要手动替换Async的执行器。方式 A全局替换 Async 执行器为虚拟线程执行器推荐import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; Configuration EnableAsync public class AsyncVtConfig { /** * 虚拟线程执行器用于Async */ Bean public TaskExecutor taskExecutor() { ExecutorService vtExecutor Executors.newVirtualThreadPerTaskExecutor(); return new org.springframework.scheduling.concurrent.ConcurrentTaskExecutor(vtExecutor); } }使用Service public class BizService { Async public void asyncHandleBiz() { // 这个方法运行在全新虚拟线程 System.out.println(Thread.currentThread().isVirtual()); } }调用// 在ControllerWeb虚拟线程中调用 bizService.asyncHandleBiz();注意newVirtualThreadPerTaskExecutor不是线程池每次提交新建虚拟线程用完销毁。方式 B单独注入 Executor手动提交任务细粒度控制Bean public ExecutorService businessVtExecutor() { return Executors.newVirtualThreadPerTaskExecutor(); }业务代码Service public class BizService { Autowired private ExecutorService businessVtExecutor; public void submitTask() { businessVtExecutor.submit(() - { // 任务运行在虚拟线程 System.out.println(Thread.currentThread().isVirtual()); }); } }✅ 最佳实践全局 VT 环境下1. 优先复用 Web 请求虚拟线程同步优先把业务逻辑写在 Controller 同步链路。优点不需要额外创建虚拟线程链路追踪、MDC 天然连贯。适用大部分 HTTP 接口串行 DB/RPC 调用。2. 并行调用场景在当前 Web 虚拟线程内开启多个虚拟线程并行在 Controller当前是 VT中使用Executors.newVirtualThreadPerTaskExecutor()并行发起多个 IO 调用。GetMapping(/order/detail) public Object getOrderDetail() throws ExecutionException, InterruptedException { try (var executor Executors.newVirtualThreadPerTaskExecutor()) { var future1 executor.submit(() - userService.getUser()); var future2 executor.submit(() - goodsService.getGoods()); return Map.of(user, future1.get(), goods, future2.get()); } }try-with-resourcesExecutorService 会自动 close等待所有虚拟线程任务完成。非常适合接口内并行调用多个 RPC/DB。⚠️ 重点坑高频踩坑1. 全局 spring.threads.virtual.enabledtrue ≠ Async 自动变成虚拟线程很多人踩这个坑Web 线程是 VT但异步任务还是平台线程。必须手动替换 Async 的 TaskExecutor。2. 不要池化虚拟线程❌ 错误写法// 错误毫无意义废掉虚拟线程能力 ExecutorService pool Executors.newFixedThreadPool(10, Thread.ofVirtual().factory());3. 并行 IO 场景必须加 Semaphore 限流哪怕是虚拟线程并行大量 RPC一定要加前面 AOP 封装的VtSemaphoreLimit防止瞬间大量 VT 打爆下游。GetMapping(/batch) public void batch() { try (var executor Executors.newVirtualThreadPerTaskExecutor()) { for(int i0;i1000;i){ executor.submit(() - { remoteService.callRpc(); // 这里方法带VtSemaphoreLimit做并发控制 }); } } }4.synchronized块内长时间 IO 阻塞会卡住载体线程 同步锁内不要放 RPC/DB 查询优先 ReentrantLock。5.MDC / 链路追踪问题Controller 主线程Web VTMDC 正常。新开虚拟线程MDC 不会自动传递需要手动拷贝 traceId。解决方案提交任务时手动把 MDC 上下文传入或者使用包装 Runnable。MDC 传递简易包装示例public static Runnable wrapWithMdc(Runnable task) { MapString, String contextMap MDC.getCopyOfContextMap(); return () - { if (contextMap ! null) { MDC.setContextMap(contextMap); } try { task.run(); } finally { MDC.clear(); } }; } // 使用 executor.submit(wrapWithMdc(() - remoteService.callRpc()));6. 调度任务 ScheduledScheduled默认使用平台线程池。如果想定时任务跑虚拟线程自定义TaskScheduler使用虚拟线程执行器。快速选型总结Controller 同步业务直接写天然跑在 Web 虚拟线程无需额外代码Controller 内并行多个 IO 请求try(newVirtualThreadPerTaskExecutor())并行提交方法异步解耦Async全局替换 TaskExecutor 为虚拟线程执行器后台独立任务注入newVirtualThreadPerTaskExecutor手动 submit总结spring.threads.virtual.enabledtrue只把 Tomcat 的 HTTP 处理线程改成虚拟线程不会自动改造业务异步任务。Controller 同步业务天然跑在虚拟线程并行 IO 可以在接口内创建虚拟线程执行器Async 需要手动替换 TaskExecutor新开虚拟线程要手动传递 MDC并且使用 Semaphore 限制下游并发。
RELATED

相关推荐

医学影像设备学综合实验台:X线机核心电路设计与实验原理解析

医学影像设备学综合实验台:X线机核心电路设计与实验原理解析

摘要医学影像设备学是医学影像技术、医学工程专业的核心课程,教学难点在于X线机高压发生器是一个高度集成的"黑箱":整流、逆变、稳压、定时、保护等多个子系统紧密耦合在一块高压油箱和控制柜里,学生在教材上看到的只是密密麻麻的电…

📅 2026/10/2 7:10:18
KITTI数据集详解:从2D目标检测到3D与SLAM评测的完整实操指南

KITTI数据集详解:从2D目标检测到3D与SLAM评测的完整实操指南

1. 为什么KITTI至今还是自动驾驶算法评测绕不开的"擂台"聊到KITTI数据集,大多数做自动驾驶视觉或者SLAM的人都不会陌生。这个由卡尔斯鲁厄理工学院和丰田美国研究院在2012年前后发布的基准数据集,直到现在依然是各大论文里出现频率最高的评测平…

📅 2026/10/2 7:10:18
从零手搓AI工程:数据管道、模型训练与部署全流程实战指南

从零手搓AI工程:数据管道、模型训练与部署全流程实战指南

1. 从零手搓AI工程:为什么我不建议你直接调包很多人一听到“AI工程”这四个字,第一反应就是打开某个云平台,拖几个组件,调一下API,跑通一个Demo,然后发个朋友圈说“今天又搞定了一个AI项目”。我承认&#…

📅 2026/10/2 7:10:18
MORE NEWS

更多资讯

📰

P0.FOC:裸机级永磁同步电机无感矢量控制实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Fenchel共轭函数详解:从几何直觉到对偶理论与近端算子

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Oracle截取JSON字符串:从SUBSTR到JSON_TABLE的完整方案

简介:面向Oracle数据库开发与运维人员,这份PDF资料聚焦在PL/SQL中提取JSON字符串指定键值这一常见需求,以自编函数parsejsonstr为例,讲解如何通过起始键与结束键精确截取目标内容,适用于数据清洗、接口联调、应用集成等…

📰

Vue3+Vite+Electron从零到打包:桌面应用开发避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

多元复合函数求导法则详解:链式法则、全导数与偏导数的区别

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Linux关机重启原理与systemd服务终止机制详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬