Tomcat是不是为每个用户创建一个线程?

Posted

技术标签:

【中文标题】Tomcat是不是为每个用户创建一个线程?【英文标题】:Does tomcat create a thread per user?Tomcat是否为每个用户创建一个线程? 【发布时间】:2011-03-25 00:56:07 【问题描述】:

我对 Web 开发还很陌生。因此,如果这是一个非常基本的问题,我深表歉意。例如,我创建了一个 Web 应用程序并将其部署到 tomcat。现在当多个用户访问 Web 应用程序时,tomcat 是否会为每个用户创建一个新线程?如果是这种情况,那么我是否仍然可以在我的应用程序本身中创建线程并期望它对由 tomcat 创建的每个用户线程保持本地?会话级数据是否跨线程保持同步?

我希望我的问题有意义。

【问题讨论】:

您可能会发现this answer 也很有帮助。 【参考方案1】:

每个请求都在不同的线程中处理。这不是“每个用户的线程”。请求是来自客户端(Web 浏览器)和服务器的任何交互。因此,在您的浏览器中输入一个 Url,调用一个 ajax 请求,每个请求都在一个单独的线程中处理。

用户在“登录”期间获得的状态(它本身不一定是登录;更好的说法是“一个用户的一组相关请求”)方便地存储在会话中.您可以使用会话存储适用于用户的任何数据,但应注意不要存储太多数据,因为它会占用内存。会话管理需要一定程度的技能。

是的,如果你启动新线程,你必须非常小心;你可以打破东西,通常这是一个坏主意。如果您必须做一些需要很长时间的事情,请使用 JMS 异步处理任何事情。另请记住,并非所有影响 Web 应用程序数据的任务都必须从 Web 应用程序调用。每天扫描数据的任务可以作为单独的任务在 Tomcat 内外运行——也就是说,您可以使用诸如石英调度程序之类的东西编写作业,甚至可以编写单独的程序并将其设置为在 cron 中运行(例如不过,请注意从您的 webapp 下更改数据的工作)。

如果您使用最好的技术,例如 Spring 和 Hibernate,它们通常会将程序员需要的对象(或者可以由应用程序开发人员配置)绑定到每个线程(使用 java 的 ThreadLocal)。

这也是创建自己的线程很危险的原因之一。如果您启动自己的线程,您可能会在请求结束时丢失绑定到初始线程的资源,这意味着如果您尝试在工作线程中访问这些资源,它们将不可用。这种类型的错误可能很难找到/修复。

edit - 正如 Stephen C 在另一个答案的评论中指出的那样,重要的是要注意通常 Tomcat(和其他容器)维护一个线程池以供使用。这意味着不必为每个请求创建一个新线程。这意味着每个请求运行在一个单独的线程中,可能会也可能不会创建或重用。

【讨论】:

感谢您的详细回答。那么,某人如何在 Web 应用程序中执行并发任务呢?即使您可以从中获得性能,通常也会避免它吗? 并发是什么意思?如果一个请求启动一个需要很长时间的任务,则需要异步处理。使用 JMS 就是这里的答案。这个想法是您将消息发送到队列或主题(并且发起请求结束),并且配置一个 bean(消息驱动 bean)来监视队列或主题并使用其上的消息,并根据消息。你需要谷歌它以了解如何实现它,但这并不难。

以上是关于Tomcat是不是为每个用户创建一个线程?的主要内容,如果未能解决你的问题,请参考以下文章

.net(C#)中,一个进程最多能创建多少线程

tomcat线程优化

Tomcat 线程优化参数说明

.net(C#)中,一个进程最多能创建多少线程

如果我想制作分布式互斥库,我是不是必须创建一个线程?

PyZMQ 是不是为每个新的客户端连接处理创建线程?