java Servlet 的多线程如何工作? [复制]

Posted

技术标签:

【中文标题】java Servlet 的多线程如何工作? [复制]【英文标题】:How does multithreading work for a java Servlet? [duplicate] 【发布时间】:2011-12-03 20:17:25 【问题描述】:

Java Servlet 生命周期由 servlet 容器管理。当第一个 web 请求进来时,容器会加载 Servlet 类,调用它的 init 方法,然后调用它的 service 方法来处理这个 web 请求。它说只能有一个 servlet 类的实例。容器创建多个线程并管理这些线程来处理多个 Web 请求(这是我所知道的)。但我想了解,鉴于 servlet 类只有一个实例,多个线程如何运行并处理多个同时的 Web 请求。有人能解释一下吗?

【问题讨论】:

仅仅因为只有一个 servlet 实例并不意味着多个执行线程不能调用该 servlet 的方法。 【参考方案1】:

一个对象实例(的方法)可以被多个线程同时调用。但是,这并不是特定于 servlet 的,而且通常是正确的。

当这种情况发生时会发生什么?每个线程仍然有自己的堆栈,这意味着每个线程都有不同的局部变量副本来处理。因此,线程之间不会有干扰,您不必担心并发调用。仅当共享资源时,例如实例/类变量被访问,可能有问题。如果实例/类变量被直接同时访问,同样的事情。

相比之下,EJB 完全按照您的建议行事。 EJB 容器确保一次只有一个线程进入 EJB 实例,因此只要不破坏 EJB 编程契约,EJB 程序员就不必担心并发性。 servlet 规范没有理由不这样做。很可能没有人在会议期间提出这个问题?它确实有一个优势,即您可以使用比 EJB 的“每个实例一个线程”更有效的并发管理。

【讨论】:

事实上,当前的设计要好得多,因为不需要多次创建实例变量(每个请求一个)。即使实例变量类似于记录器或数据服务的句柄,也可以简单地共享。 所以在 servlets 服务方法中,任何共享资源,例如:文件处理程序,用于数据库访问的变量,都需要适当保护以进行多线程访问?【参考方案2】:

在初始化完成之前,servlet 不会被并发调用。完成此操作后,所有调用都会在您的 servlet 上同时执行。这意味着如果需要同时处理两个请求,则可以由两个并发线程调用service 方法。

如果这种行为不适合您(例如,如果您正在使用某种非线程安全资源)并且确实确定您不希望您的方法被多个线程同时调用,您可以标记您的service 方法为synchronized

【讨论】:

我认为在服务方法上同步并不是一个好主意,这意味着 servlet 一次只处理一个请求,而这只是一个非常慢的 Web 应用程序的秘诀。 ..相反,最好在多个线程正在访问的资源上进行同步...

以上是关于java Servlet 的多线程如何工作? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

servlet的多线程并发问题

java的多线程学习,第三记

Servlet编程:如何使用Servlet

编程模式中的多线程和数据作用域

Servlet的线程安全问题

Servlet的线程安全问题