[英]Why Tomcat is using different threads when request url is same and handled with CompletableFuture?
I have used this sample in github using CompletableFuture.我已经使用 CompletableFuture 在 github 中使用了这个示例。
I tried running /asyncCompletable endpoint from several tabs in browser(chrome) simultaneously.我尝试同时从浏览器(chrome)中的多个选项卡运行 /asyncCompletable 端点。 The point is as Tomcat is Servlet Container and it has it's own Servlet Thread Pool, thus hitting same endpoint url from different tabs in browser wouldn't necessarily use same main-thread.
关键是因为 Tomcat 是 Servlet 容器,它有自己的 Servlet 线程池,因此从浏览器中的不同选项卡访问相同的端点 url 不一定使用相同的主线程。 see my console log below:
请参阅下面的控制台日志:
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
As you see it is using different threads for each browser tab for the same URL and not reusing the released thread for further calls.如您所见,它为同一 URL 的每个浏览器选项卡使用不同的线程,而不是重新使用已发布的线程进行进一步调用。 What I mean is that it is not reusing the released thread (for example http-nio-9191-exec-7) for next incoming request.
我的意思是它不会为下一个传入请求重用已发布的线程(例如 http-nio-9191-exec-7)。 Why is that?
这是为什么?
A thread pool is what it states - a pool.线程池就是它所说的 - 一个池。 So there's no guarantees in a pool to re-address the same thread to a task nor would it be any helpful.
因此,池中不能保证将同一线程重新寻址到任务,也没有任何帮助。 The pool just return the next available thread in the pool.
池只是返回池中的下一个可用线程。 But what does "next" mean?
但是“下一步”是什么意思? This is depending on the pool implementation - and this should be abstracted from the user.
这取决于池实现 - 这应该从用户那里抽象出来。 Just because it's not directly reassigned the next request doesn't mean it will never be reused.
仅仅因为它没有直接重新分配下一个请求并不意味着它永远不会被重用。 The pool decides how to do this.
池决定如何做到这一点。 This depends in the pool's strategy.
这取决于池的策略。 So there might be some margin or threshold in time or some queue in the Servlet pool.
因此,在 Servlet 池中可能有一些余量或时间阈值或一些队列。
You could try if behaviour changes when you reconfigure Tomcat for evaluation purpose:您可以尝试在重新配置 Tomcat 以进行评估时行为是否发生变化:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="0"/>
But this will not be helpful performance wise and is not suggested.但这对性能没有帮助,不建议这样做。 I wouldn't mess with the Servlet Thread Pool mechanics unless there's good reasons to do so.
除非有充分的理由,否则我不会弄乱 Servlet 线程池机制。 A pool is for handing over that control for good reasons.
池用于出于充分的理由移交该控制权。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.