处理器线程、tomcat线程、java线程

piv4azn7  于 2021-10-10  发布在  Java
关注(0)|答案(1)|浏览(653)

关闭。这个问题需要更加关注。它目前不接受答案。
**想改进这个问题吗?**编辑这篇文章,更新这个问题,使它只关注一个问题。

两个月前关门了。
改进这个问题
有人能给我解释一下处理器线程、tomcat线程和java线程之间的区别及其关系吗?
据我所知:处理器有一定数量的内核。如果我有一个双核机器,它将为我提供4个线程。tomcat也有许多线程(默认值为200),java也可以有许多线程,可以在每次需要时创建,也可以从我可以配置的线程池中获取。
我对调用端点时发生的情况的理解如下(假设我有一个双核->4线程):
我打电话到“/myendpoint”
我的调用将使用一个处理器线程->处理器线程将请求发送到tomcat的一个线程->它也将请求发送到myapplication的主线程
我的应用程序有以下选项:a。自行解决请求,并将答案返回给tomcat线程,而tomcat线程又将其返回给处理器线程。B将请求发送到我创建的一个线程或我配置的线程池中的一个线程,等待应答并将应答发送回tomcat线程,tomcat线程将返回给处理器线程。第一个问题是:线程createdbyme/threadpoolthread是否使用剩余可用的其他3个处理器线程之一(我的逻辑是肯定的)
当我开始同时考虑大量请求时,问题就出现了:
300人打电话到“/myendpoint”
由于我的处理器只有2个内核(4个线程),我猜一次需要4个请求,剩下的296个请求被放入某种队列中,直到前4个请求被处理。
这四个请求被发送到tomcat,tomcat也将它们进一步发送到java应用程序。第二个问题是在这一点上:如果我的应用程序的主线程将请求发送到一个线程createdbyme/threadpoolthread,那么该线程应该如何工作,因为我的处理器的所有4个线程都在步骤2中使用?
我在这里和其他页面上读了很多问题,但没有找到一些东西来展示一个请求的整个生命周期(或者至少让它更清楚),也没有找到一些多个请求的例子(300个请求的例子中处理器线程数较少)(processorthread->tomcatthread->javathread->tomcatthread->processorthread)
生命周期的一些图形化表示肯定会使它更易于理解。如果您能提供有关此问题的任何信息,并更正我所写行中的信息,我将不胜感激
这是一种有助于解释的图表

thigvfpy

thigvfpy1#

截至2021年,所有基于openjdk代码库的常用java实现都将java线程作为主机os线程实现。jvm中的每个java线程对应于操作系统中的一个线程(这可能会随着project loom技术的发展而改变。)
每个java应用程序都从一个线程开始。ApacheTomcat是一个java应用程序。tomcat从一个线程开始。然后,tomcat可以自由地生成它认为合适的额外线程。
虽然我不知道tomcat的内部结构,但通常进入这样一个服务器的每个请求都被分配给一个线程。在该线程中构建了一个响应。通常,web服务器部分(tomcat中的catalina)维护一个线程,专用于侦听传入请求。该线程将每个请求分派给新的或回收的线程进行处理。如果web服务器被请求压得喘不过气来,服务器可能会选择如您所述在队列中短暂保留它们。或者web服务器可以选择取消请求,将相应的http错误发送回web客户端。
基于主机os线程的java线程有优缺点,也有权衡。缺点之一是线程数量的实际限制相对较低(上面提到的ProjectLowe试图解决这个问题,一次可以处理数百万条线程。)
我怀疑您所谓的“处理器线程”实际上是错误地标记了服务器(如tomcat)的主java线程。如上所述,该主线程可能会启动一个java线程来侦听请求。该侦听线程启动其他线程来处理请求。在基于Javaservlet的服务器上,请求处理线程调用servlet代码。您的servlet代码可能会选择生成一个或多个线程,可能是通过执行器服务。或者,如果在符合jakarta ee的服务器上,您的servlet代码可能会选择使用内置的jakarta并发特性来更轻松地在其他线程上完成任务。
注意,这些都是java线程:tomcat主线程、请求处理线程和其他后台线程。你的术语似乎暗示这些是不同类型的线程。但它们并不是不同的类型,至少在纯java构建的web服务器和servlet引擎(如ApacheTomcat和EclipseJetty)上不是这样。
你说:
将该请求发送到myapplication的主线程
作为servlet程序员,我们可以方便地将web应用程序视为实际应用程序,但实际上它并不是一个应用程序。您的web应用程序只是零个、一个或多个线程,每个线程处理传入的请求。没有web应用程序的“主线程”。Map到特定servlet的每个请求都会导致另一个线程运行该servlet的代码。内存中的一个对象代表您的特定servlet,许多线程可能运行与您相同的servlet代码,每个线程都服务于客户机。
你说:
. 将请求发送到我创建的一个线程或我配置的线程池中的一个线程,等待应答并将应答发送回tomcat线程,tomcat线程将返回给处理器线程。
您的代码可以选择生成线程。你应该谨慎地做出选择。servlet环境已经定义为高度线程化。如果部署中同时有许多用户,则会阻止您在多个线程上运行冗长的任务。相比之下,对于用户数量较少的部门的内部服务器,您可能不担心达到实际限制。
当第一个线程等待时,在单个线程上运行单个任务是对资源的浪费,因为第一个线程可以自己完成工作。
你说:
线程createdbyme/threadpoolthread是否使用剩余可用的其他3个处理器线程之一?
您启动的任何线程都只是java线程,与servlet引擎使用的java线程相同。现在所有的java线程都与主机os线程一一对应。当这些线程执行时,它们执行的时间以及在哪个处理器上执行由jvm和主机操作系统决定。这种行为会因计算机而异。这种行为在运行时会有所不同,这取决于不断变化的运行时条件。作为servlet程序员,这种行为不在我们的控制之下。
你说:
第二个问题是在这一点上:如果我的应用程序的主线程将请求发送到一个线程createdbyme/threadpoolthread,那么该线程应该如何工作,因为我的处理器的所有4个线程都在步骤2中使用?
a) 没有像你的web应用程序的主线程这样的东西。每个传入请求都分配了一个线程。
b) 您通常不会将请求传递给其他线程。您已经有了一个专用于处理请求的线程,即servlet引擎分配的线程。这是servlet引擎的主要任务之一,用于管理分配给请求的线程。如果您决定生成线程,那么它将用于以下工作:运行三个不同的数据库查询,以构建一个复杂的报告,作为返回给用户的响应的一部分。
c) 线程通常会暂停在cpu内核上运行。jvm和主机操作系统一起冻结一个线程,以便给另一个线程更多的运行时间。这个过程有开销,这是避免机器因线程过多而负担过重的原因之一(同样,当ProjectLowe到达时,这可能会改变,因为jvm将处理“虚拟线程”(光纤)的调度,而不需要主机操作系统的太多参与。这将使线程变得非常“便宜”,这意味着更快,同时更有效地使用更少的内存。)
诸如ApacheTomcat和EclipseJetty之类的servlet引擎可能在幕后专门处理线程以优化其性能。我在上面的讨论中忽略了这一事实,因为我们作为servlet编码人员对优化没有感觉,也无法控制它。从概念上讲,我相信上面的讨论是合理的,但不一定完全准确,这取决于这些潜在的优化。
此外,在未来的ProjectLoom技术下,这些优化可能会发生变化。作为servlet编码人员,所有这些对我们来说都是透明的。这就是servlet技术的要点,它可以使我们的servlet编码人员免受实现服务器的这些细节的影响。

相关问题