如果您可以在应用程序中使用虚拟线程,则更喜欢使用后一种方法,即invoke both the REST API calls using 101.在第#Represent Every Concurrent Task as a Virtual Thread; Never Pool Virtual Threads节下的虚拟线程文档中甚至提出了扇出场景的类似用例.
第一种方法
Spring本身将利用虚拟线程来处理向服务器发起的请求.这主要意味着每个请求都将被分配给一个由Tomcat处理的新虚拟线程,并且这些线程可以根据每个请求中执行的I/O切换到接受更高的吞吐量和并发性的其他请求.
但是,一旦为线程分配了请求(考虑跟踪request-id
),它将执行所有后续同步步骤,直到它在同一线程内响应.如果日志(log)可以帮助您进行关联,则会产生如下输出:
GreetingsController : 34ace5cc-2b6b-4226-a088-b5888fc30f99 : VirtualThread[#568,tomcat-handler-51]/runnable@ForkJoinPool-1-worker-10
WebPageService : 34ace5cc-2b6b-4226-a088-b5888fc30f99 : tomcat-handler-51 : /uri1
WebPageService : 34ace5cc-2b6b-4226-a088-b5888fc30f99 : tomcat-handler-51 : /uri2
二方法
通过使用newVirtualThreadPerTaskExecutor
的方法,您可以将所有的服务调用作为一个任务并发地分配给一个新的虚拟线程.在这种情况下,应用程序会进一步为您提交的每个服务调用从common ForkJoinPool
生成新的虚拟线程.以下是该 case 的日志(log)供参考:
GreetingsController : ad39b86e-073c-479e-a5d8-ec35bbb34dac : VirtualThread[#575,tomcat-handler-54]/runnable@ForkJoinPool-1-worker-12
WebPageService : ad39b86e-073c-479e-a5d8-ec35bbb34dac : VirtualThread[#576]/runnable@ForkJoinPool-1-worker-12: /uri1
WebPageService : ad39b86e-073c-479e-a5d8-ec35bbb34dac : VirtualThread[#580]/runnable@ForkJoinPool-1-worker-12 : /uri2
Side Note -上述日志(log)中的线程名是在调试器的帮助下添加的.
此外,对于您有关试用资源的用法的问题,请引用引用的链接,总结新引入的ExecutorService.close
:
close
方法,在try 结束时隐式调用
块将自动等待提交给
ExecutorService-即由
ExecutorService-终止.
这肯定有助于释放其他线程使用的资源,并减少应用程序中任何可能的泄漏.