当请求url相同并且使用CompletableFuture处理时,Tomcat为什么使用不同的线程



我使用CompletableFuture在github中使用了这个示例。

我尝试同时从浏览器(chrome(中的几个选项卡运行/asyncCompletable端点。关键是Tomcat是Servlet容器,它有自己的Servlet线程池,所以从浏览器中的不同选项卡中访问相同的端点url不一定会使用相同的主线程。请参阅下面的控制台日志:

8:07:07.334 [http-nio-9191-exec-8] Request received
18:07:07.335 [http-nio-9191-exec-8] Servlet thread released
18:07:07.335 [ForkJoinPool.commonPool-worker-3] Start processing request
18:07:08.262 [http-nio-9191-exec-7] Request received
18:07:08.262 [http-nio-9191-exec-7] Servlet thread released
18:07:08.262 [ForkJoinPool.commonPool-worker-4] Start processing request
18:07:08.860 [http-nio-9191-exec-9] Request received
18:07:08.861 [http-nio-9191-exec-9] Servlet thread released
18:07:08.861 [ForkJoinPool.commonPool-worker-5] Start processing request
18:07:09.376 [http-nio-9191-exec-10] Request received
18:07:09.377 [http-nio-9191-exec-10] Servlet thread released

正如您所看到的,它为同一URL的每个浏览器选项卡使用不同的线程,而不重用已发布的线程进行进一步的调用。我的意思是,它不会为下一个传入请求重用已发布的线程(例如http-nio-9191-sec-7(。为什么?

线程池就是它所说的池。因此,在池中不能保证将同一线程重新寻址到任务,也不会有任何帮助。池只返回池中的下一个可用线程。但是";下一个";意思是这取决于池的实现——这应该从用户那里抽象出来。下一个请求没有被直接重新分配并不意味着它永远不会被重用。游泳池决定如何做到这一点。这取决于游泳池的策略。因此,Servlet池中可能存在一定的时间余量或阈值或队列。

当您为评估目的重新配置Tomcat时,您可以尝试行为是否发生变化:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="0"/>

但这对性能没有帮助,也不建议这样做。除非有充分的理由,否则我不会破坏Servlet线程池机制。

最新更新