非Spring Boot的Spring MVC应用Virtual Threads无法用于请求控制器方法
在非Spring Boot的Spring MVC里给控制器请求启用虚拟线程
你这情况我碰到过,定时任务能用虚拟线程但控制器不行,结合你的环境(Spring6.1 XML配置、Java21、Tomcat10.1.18),按下面几步调就行:
1. 把Tomcat的虚拟线程执行器绑定到Connector
你已经配了StandardVirtualThreadExecutor,但Connector得明确指定用这个执行器,不然Tomcat可能还是用默认线程池。改下server.xml的Connector配置,加个executor属性指向你的虚拟线程执行器:
<Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/> <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443" maxPostSize="-1" useVirtualThreads="true" executor="tomcatThreadPoolVirtual" <!-- 新增这行 --> />
Tomcat的useVirtualThreads属性得绑定了虚拟线程执行器才会真生效,不然只是个标记,实际还是用默认池。
2. 给Spring MVC的请求处理配虚拟线程池
非Spring Boot的Spring MVC默认用Servlet容器的线程处理请求,要让控制器方法也用虚拟线程,得给RequestMappingHandlerAdapter指定支持虚拟线程的TaskExecutor,在Spring XML里加这段:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="taskExecutor"> <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"> <property name="virtualThreads" value="true"/> </bean> </property> </bean>
这样Spring MVC处理控制器方法时就会用虚拟线程跑逻辑了。
3. 验证的时候别只看isVirtual()
除了Thread.currentThread().isVirtual(),可以在控制器里打印线程名,虚拟线程的名字一般带virtual-前缀,比如virtual-1,一眼就能判断:
@GetMapping("/test") public String test() { System.out.println("当前线程:" + Thread.currentThread().getName() + ",是否虚拟线程:" + Thread.currentThread().isVirtual()); return "ok"; }
4. 检查Java启动参数
Java21默认启用虚拟线程,但要是启动命令里加了--disable-preview就会禁用,所以得确认启动参数里没这个配置。
按这几步调完,控制器请求应该就能用上虚拟线程了。
内容的提问来源于stack exchange,提问作者Kory
相关产品推荐
相关产品推荐

