2010-08-04 53 views
18

我对web开发相当陌生。所以我很抱歉如果这是一个非常基本的问题。例如,我创建一个Web应用程序并将其部署到tomcat。现在,当多个用户点击Web应用程序时,tomcat是否为每个用户创建一个新线程?如果是这样的话,我还可以在我的应用程序本身中创建线程,并希望它保持本地到tomcat创建的每个用户线程?会话级数据是否在线程间保持同步?tomcat是否为每个用户创建一个线程?

我希望我的问题有道理。

+2

你可能会发现[这个答案](http://stackoverflow.com/questions/3106452/java-servlet-instantiation-and-session-variables/3106909#3106909)也很有帮助。 – BalusC 2010-08-04 01:51:56

回答

35

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

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

是的,你必须非常小心,如果你发射新线程;你可以破坏事物,通常是一个坏主意。如果你必须做一些需要很长时间的事情,那么使用JMS来处理异步的任何事情。另外请记住,并非所有影响Web应用程序数据的任务都必须从webapp调用。每天扫描数据的任务可以作为一个单独的任务在tomcat中运行或不运行 - 也就是说,您可以使用诸如quartz调度程序之类的东西编写任务,甚至编写单独的程序并将其设置为在cron中运行(是尽管如此,小心改变webapp下的数据)。

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

这也是开始你自己的线程是危险的原因之一。如果您启动自己的线程,那么在请求结束时,可能会丢失绑定到初始线程的资源,这意味着如果尝试访问工作线程中的这些资源,则无法使用它们。这种类型的错误可能是寻找/修复屁股的痛处。

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

+1

感谢您的详细解答。某人在Web应用程序中如何执行并发任务?即使你可以从中获得表现,它通常是可以避免的吗? – user377067 2010-08-04 02:03:19

+2

你是什么意思的并发?如果请求启动需要很长时间的任务,则需要异步处理。使用JMS是这里的答案。这个想法是你发送一个消息到一个队列或主题(并且发起请求结束),并且一个bean(消息驱动的bean)被配置为观察队列或者主题并且消费它上面的消息,并且基于消息。你需要谷歌来找出如何实现它,但它并不困难。 – hvgotcodes 2010-08-04 02:07:32

+0

我很感激。 – user377067 2010-08-04 02:10:19

相关问题