Why Servlets are not thread Safe?
我需要知道为什么servlet不是线程安全的?在Struts2.0框架控制器中,servlet线程安全的原因是什么?
I need to know why the servlets are not thread safe ?
Servlet实例本质上不是线程安全的,因为Java编程语言一般具有多线程特性。Java虚拟机支持通过多个线程执行相同的代码。对于具有多个处理器的机器来说,这是一个很大的性能优势。这还允许多个并发用户执行相同的代码,而不会相互阻塞。
设想一个拥有4个处理器的服务器,其中一个普通的servlet可以每秒处理1000个请求。如果这个servlet是线程安全的,那么Web应用程序的行为就好像它运行在一个拥有1个处理器的服务器上,其中servlet每秒只能处理250个请求(好吧,这并不完全是这样的,但是你知道了)。
如果在使用servlet时遇到线程安全问题,那么这是您的错误,而不是Java或Servlet的错误。您需要修复servlet代码,这样就不会将请求或会话范围的数据分配为servlet的实例变量。有关深入的解释,请参见servlet如何工作?实例化、会话、共享变量和多线程。
And whats the reason that in Struts 2.0 framework controller servlet is thread safe ?
它不是线程安全的。您将Struts Dispatcherservletfilter与Struts actions混淆。Struts操作在每个请求上都被重新创建。所以每个请求都有自己的请求范围struts操作实例。Struts Dispatcherservletfilter不将它们存储为自己的实例变量。相反,它将其存储为EDOCX1的一个属性(0)。
servlet是普通的Java类,因此不是线程安全的。
但是,如果没有实例变量,Java类是线程安全的。只有实例变量需要同步。(实例变量是在类中声明的变量,而不是在其方法中声明的变量。
方法中声明的变量是线程安全的,因为每个线程创建自己的程序堆栈,函数变量在堆栈中分配。这意味着方法中的变量是为每个线程创建的,因此没有任何关联的线程同步问题。
方法变量是线程安全的,类变量不是。
每个servlet映射只有一个servlet实例;所有实例属性在所有请求之间共享。访问这些属性必须考虑到这一点。
struts 2个动作(不是"控制器servlet",它们既不是servlet也不是控制器)在每个请求中被实例化。操作属性只能由单个请求的线程访问。
servlet不是线程安全的,但是我们可以通过将servlet类实现到
1 2 3 4 5 6 | public class SurveyServlet extends HttpServlet implements SingleThreadModel { servlet code here.. ... } |
servlet通常是多线程的。
Servlet容器通常通过为每个请求创建一个新的Java线程来管理并发请求。新线程被赋予对请求的servlet的对象引用,后者通过同一线程发出响应。这就是为什么在编写servlet时设计并发性很重要的原因,因为同一个servlet实例可以处理多个请求。
servlet容器处理servlet请求的方式取决于实现;它们可以使用单个servlet,也可以使用servlet池,这取决于供应商的系统架构。
Struts2动作对象是为每个请求实例化的,因此没有线程安全问题。
servlet本身不是线程安全的。通过使服务方法同步,可以使其线程安全。您需要实现singleThreadInterface以使其线程安全。