Servlets 为什么servlet不是线程安全的?

Servlets 为什么servlet不是线程安全的?,servlets,Servlets,我需要知道为什么servlet不是线程安全的?Struts 2.0框架控制器servlet是线程安全的原因是什么?servlet本身不是线程安全的。您可以通过同步服务方法使其线程安全。 您需要实现SingleThreadInterface以使其线程安全。每个servlet映射有一个servlet实例;所有实例属性在所有请求之间共享。对这些属性的访问必须考虑到这一点 Struts 2操作(不是“控制器servlet”,它们既不是servlet也不是控制器)根据请求实例化。操作属性只能由单个请求的线

我需要知道为什么servlet不是线程安全的?Struts 2.0框架控制器servlet是线程安全的原因是什么?

servlet本身不是线程安全的。您可以通过同步服务方法使其线程安全。
您需要实现SingleThreadInterface以使其线程安全。

每个servlet映射有一个servlet实例;所有实例属性在所有请求之间共享。对这些属性的访问必须考虑到这一点


Struts 2操作(不是“控制器servlet”,它们既不是servlet也不是控制器)根据请求实例化。操作属性只能由单个请求的线程访问。

servlet通常是多线程的

Servlet容器通常通过为每个请求创建一个新的Java线程来管理并发请求。向新线程提供对请求的servlet的对象引用,该servlet通过同一线程发出响应。这就是为什么在编写servlet时设计并发性很重要的原因,因为多个请求可能由同一个servlet实例处理

servlet容器处理servlet请求的方式取决于实现;他们可以使用单个servlet,也可以使用servlet池,这取决于供应商的系统架构

Struts 2 Action对象是为每个请求实例化的,因此不存在线程安全问题

我需要知道为什么servlet不是线程安全的

Servlet实例本质上不是线程安全的,因为Java编程语言通常具有多线程特性。Java虚拟机支持通过多个线程执行相同的代码。这对于具有多个处理器的机器来说是一个巨大的性能优势。这还允许多个并发用户执行相同的代码,而不会相互阻塞

想象一下,一个服务器有4个处理器,其中一个普通servlet每秒可以处理1000个请求。如果servlet是线程安全的,那么web应用程序的行为就像它运行在一个具有1个处理器的服务器上,其中servlet每秒只能处理250个请求(好吧,这并不完全是这样的,但你已经知道了)

如果您在使用Servlet时遇到线程安全问题,那么这是您的错误,而不是Java或Servlet的错误。您需要修复servlet代码,这样就不会将请求或会话范围的数据指定为servlet的实例变量。有关详细说明,请参见

Struts 2.0框架控制器servlet是线程安全的原因是什么


它不是线程安全的。您将Struts dispatcher servlet过滤器与Struts操作混淆了。struts操作会在每个请求上重新创建。因此,每个请求都有自己的请求范围Struts操作实例。Struts dispatcher servlet过滤器不会将它们存储为自己的实例变量。相反,它将其存储为
HttpServletRequest

的一个属性,Servlet不是线程安全的,但是我们可以通过将Servlet类实现为
SingleThreadModel
类似于下面给出的类定义,但性能问题仍然存在,因此更好的选择是使用同步部分

public class SurveyServlet extends HttpServlet
                           implements SingleThreadModel
{
servlet code here..
...
}

servlet是普通的java类,因此不是线程安全的

但也就是说,如果没有实例变量,Java类是线程安全的。只有实例变量需要同步。(实例变量是在类中声明的变量,而不是在其方法中声明的变量

方法中声明的变量是线程安全的,因为每个线程创建自己的程序堆栈,函数变量在堆栈中分配。这意味着方法中的变量是为每个线程创建的,因此没有任何与线程同步相关的问题


方法变量是线程安全的,类变量不是。

谁告诉你servlet不是线程安全的?@b我肯定不会称它们为“线程安全的”,尽管我要警告说,这完全取决于实现。传统智慧称之为非线程安全。相关:欢迎使用堆栈溢出。请阅读,并且。如果servlet不是线程安全的,那么所有Java web AP如何能够完美地工作,即使不让它们实现SingleThreadInterface?如果您使用错误地删除它们。如果您这样做,它们是线程安全的。S2实际上使用了一个过滤器,而不是servlet,这与JEE指南相反:/n不太确定,只有实例变量需要同步。静态变量也需要同步,它们不是实例变量。这是错误的,需要按照@ParamvirSinghKarwal进行更正在java中,在类级别(而非方法级别)声明的变量分为两类:静态变量(又名类变量)和实例变量(属于对象的变量)。说“只有实例变量需要同步”是令人困惑的“只有在类级别声明的变量(静态变量和实例变量)需要同步。”-只有在阅读完整答案后,您的意图才会清楚。