处理器线程、Tomcat 线程、Java 线程

如何解决处理器线程、Tomcat 线程、Java 线程

谁能解释一下处理器线程、tomcat线程和Java线程之间的区别以及它们之间的关系?

据我所知: 处理器具有一定数量的内核。我有一台双核机器,它将为我提供 4 个线程。 Tomcat 也有多个线程(默认值为 200) 而且 Java 也可以有多个线程,可以在每次需要时创建,也可以从可以配置的 ThreadPool 中获取。

我对调用端点时会发生什么的理解是这样的(假设我有一个双核 -> 4 个线程):

  1. 我打电话给“/myEndpoint”
  2. 我的调用将使用处理器线程之一 -> 处理器线程将请求发送到 Tomcat 的线程之一 -> 该线程也会将该请求发送到 MyApplication 的主线程
  3. 我的应用程序有以下选项: 一种。自行解决请求并将答案返回给 Tomcat 线程,后者又将其返回给处理器线程。 湾将请求发送到由我创建的线程之一或我配置的ThreadPool中的线程之一,等待应答并将应答发送回Tomcat线程这反过来将它返回给处理器线程。此时的第一个问题是:线程 createdByMe / threadPoolThread 是否使用了其他 3 个可用的处理器线程之一? (我的逻辑是肯定的)

当我开始同时考虑大量请求时,问题就出现了:

  1. 300 人呼叫“/myEndpoint”
  2. 由于我的处理器只有 2 个内核(4 个线程),我猜它一次需要 4 个请求,而剩余的 296 个请求会放入某种队列中,直到处理前 4 个请求。
  3. 这四个请求被发送到 Tomcat,后者也将它们进一步发送到 Java 应用程序。 在这一点上的第二个问题:如果我的应用程序的主线程将请求发送到线程 createdByMe / threadPoolThread 由于所有 4 个线程,该线程应该如何工作我的处理器用于第 2 步?

我在这里以及其他页面上阅读了很多问题,但没有设法找到一些内容来呈现请求的完整生命周期(或至少使其更清晰)以及多个请求的一些示例(具有较少处理器线程数的 300 个请求示例)(processorThread -> TomcatThread -> JavaThread -> TomcatThread -> processorThread )

生命周期的一些图形表示肯定会让它更容易理解。我将不胜感激有关此问题的任何信息以及更正我所写的行中显示的信息

The kind of diagram that would be useful for an explanation

解决方法

截至 2021 年,所有基于 OpenJDK 代码库的常用 Java 实现都将 Java thread 实现为主机 OS 线程。 JVM 中的每个 Java 线程对应于 OS 中的一个线程。 (这在未来可能会随着 Project Loom 技术而改变。)

每个 Java 应用都从一个线程开始。 Apache Tomcat 是一个 Java 应用程序。 Tomcat 从一个线程开始。然后 Tomcat 可以自由地产生它认为合适的其他线程。

虽然我不知道 Tomcat 的内部结构,但通常每个进入此类服务器的请求都会分配给一个线程。在那个线程中建立了一个响应。通常,Web 服务器部分(Tomcat 中的Catalina)维护一个专用于侦听传入请求的线程。该线程将每个请求分派给新的或回收的线程进行处理。如果 Web 服务器被请求淹没,服务器可能会选择将它们短暂地放在队列中,如您所提到的。或者 Web 服务器可以选择取消请求,将相应的 HTTP 错误发送回 Web 客户端。

基于主机操作系统线程的 Java 线程有利有弊,权衡利弊。缺点之一是线程数量的实际限制相对较低。 (上面提到的 Loom 项目试图解决这个问题,允许一次处理数百万个线程。)

我怀疑您所说的“处理器线程”实际上是错误地标记了服务器(例如 Tomcat)的主 Java 线程。如上所述,该主线程可能会启动一个 Java 线程来侦听请求。该侦听线程启动其他线程来处理请求。在基于 Java Servlet 的服务器上,该请求处理线程调用您的 Servlet 代码。您的 Servlet 代码可能会选择生成一个或多个线程,可能是通过执行程序服务。或者,如果在符合 Jakarta EE 的服务器上,您的 Servlet 代码可能会选择使用内置的 Jakarta Concurrency 功能来更轻松地在其他线程上完成任务。

注意这些都是Java线程:Tomcat主线程、请求处理线程、附加后台线程。您的术语似乎暗示这些是不同种类的线程。但它们并不是不同的种类,至少不是在纯 Java 中构建的 Web 服务器和 Servlet 引擎上,例如 Apache Tomcat 和 Eclipse Jetty。

你说:

将该请求发送到 MyApplication 的主线程

虽然我们作为 Servlet 程序员发现将我们的 Web 应用程序视为一个实际的应用程序很方便,但它实际上并不是一个应用程序。您的 Web 应用程序只是零个、一个或多个线程,每个线程处理传入的请求。 Web 应用程序没有“主线程”。每个映射到特定 Servlet 的请求都会导致另一个线程运行该 Servlet 的代码。内存中的一个对象代表您的特定 Servlet,许多线程可能正在运行与您完全相同的 Servlet 代码,每个线程都为一个客户端提供服务。

你说:

。将请求发送到我创建的线程之一或我配置的 ThreadPool 中的线程之一,等待答案并将答案发送回 Tomcat 线程,Tomcat 线程将其返回给处理器线程。

您的代码可能会选择生成线程。你应该谨慎地做出这个选择。根据定义,Servlet 环境已经是高度线程化的。期望部署中有许多并发用户应该会阻止您在多个线程上运行冗长的任务。相比之下,对于用户数量较少的部门使用内部服务器,您可能不必担心达到实际限制。

在第一个线程等待时在单个线程上运行单个任务是对资源的浪费,因为第一个线程可以简单地自己完成工作。

你说:

线程 createdByMe / threadPoolThread 是否使用了其他 3 个可用的处理器线程之一?

您启动的任何线程都只是 Java 线程,与您的 Servlet 引擎使用的 Java 线程相同。所有 Java 线程(现在)都与主机操作系统线程一对一映射。当这些线程执行时,它们执行多长时间以及它们在哪个处理器上执行,由 JVM 和主机操作系统决定。这种行为会因一台计算机而异。该行为在运行时会有所不同,具体取决于不断变化的运行时条件。这种行为不受我们作为 Servlet 编码人员的控制。

你说:

此时的第二个问题是:如果我的应用程序的主线程将请求发送到一个线程 createdByMe / threadPoolThread,由于我的处理器的所有 4 个线程都在第 2 步使用,该线程应该如何工作?

A) 没有 Web 应用程序的主线程之类的东西。每个传入请求都分配了一个线程。

B) 您通常不会将请求传递给其他线程。 您已经有一个线程专用于处理请求,这是 Servlet 引擎分配的线程。这是 Servlet 引擎的主要工作之一,用于管理分配给请求的线程。如果您决定生成线程,则将用于诸如运行三个不同的数据库查询之类的工作,以便构建复杂的报告作为返回给用户的响应的一部分。

C) 线程通常会暂停在 CPU 内核上运行。 JVM 和主机操作系统协同工作以冻结一个线程,以便为另一个线程提供更多运行时间。此过程存在开销,这是避免因过多线程而使计算机负担过重的原因之一。 (同样,当 Loom 项目到来时,这可能会改变,因为 JVM 将处理“虚拟线程”(fibers)的调度,而没有主机操作系统的太多参与。这将使线程非常“便宜”,意味着很多更快,同时更有效地使用更少的内存。)


Apache Tomcat 和 Eclipse Jetty 等 Servlet 引擎可能在幕后进行专门的线程处理以优化其性能。我在上面的讨论中忽略了这个事实,因为我们作为 Servlet 编码人员没有这种优化的感觉,也无法控制它。从概念上讲,我认为上述讨论是合理的,但不一定完全准确,具体取决于这些潜在的优化。

此外,此类优化将来可能会在 Project Loom 技术下发生变化。所有这些对我们作为 Servlet 编码人员来说都是透明的。这就是 Servlet 技术的重点,使我们 Servlet 编码人员免受实现服务器的这些细节的影响。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res