Servlet容器启动时,会对每一个Servlet对象实例化一次,而且是仅仅一次,在运行的时候,不管多少个请求都是同时执行这一个Servlet对象实例。也就是说Servlet对象是单实例多线程,这个时候,就需要注意到并发安全问题。
一、为什么不安全
先看两个定义:
- 实例变量:实例变量在类中定义。类的每一个实例都拥有自己的实例变量,如果多个线程同时访问该实例的方法,而该方法又使用到实例变量,那么这些线程同时访问的是同一个实例变量,会共享该实例变量。
- 局部变量:局部变量在方法中定义。每当一个线程访问局部变量所在的方法时,在线程的堆栈中就会创建这个局部变量,线程执行完这个方法时,该局部变量就被销毁。所有多个线程同时访问该方法时,每个线程都有自己的局部变量,不会共享。
例如:
public class MyServlet extends HttpServlet{ private static final long serialVersionUID = 1L; private String userName1 = null;//实例变量 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ userName1 = req.getParameter("userName1"); String userName2 = req.getParameter("userName2");//局部变量 //TODO 其他处理 } }
userName1则是共享变量,多个线程会同时访问该变量,是线程不安全的。
userName2是局部变量,不管多少个线程同时访问,都是线程安全的。
二、怎么解决
- 如果不涉及到全局共享变量,全部放到局部变量,最好的做法
- 如果使用到全局共享的场景,可以使用加锁的方式,比如
public class MyServlet extends HttpServlet{ private static final long serialVersionUID = 1L; private String userName1 = null;//实例变量 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ synchronized (userName1) { userName1 = req.getParameter("userName1"); //TODO } String userName2 = req.getParameter("userName2");//局部变量 //TODO 其他处理 } }
或者使用线程安全的StringBuffer去代替String,
或者使用线程安全的容器比如: java.util.concurrent.ConcurrentHashMap 等等
最好使用乐观锁的形式去加锁
相关推荐
javax.servlet-api-***.jar中文文档.zip,java,javax.servlet-api-***.jar,javax.servlet,javax.servlet-api,***,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,javax,servlet,api,中文API文档,手册,开发...
赠送jar包:jakarta.servlet-api-4.0.4.jar; 赠送原API文档:jakarta.servlet-api-4.0.4-javadoc.jar; 赠送源代码:jakarta.servlet-api-4.0.4-sources.jar; 赠送Maven依赖信息文件:jakarta.servlet-api-4.0.4....
javax.servlet-api-***.jar中文文档.zip,java,javax.servlet-api-***.jar,javax.servlet,javax.servlet-api,***,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,javax,servlet,api,中文API文档,手册,开发...
赠送jar包:javax.servlet-api-4.0.0.jar; 赠送原API文档:javax.servlet-api-4.0.0-javadoc.jar; 赠送源代码:javax.servlet-api-4.0.0-sources.jar; 赠送Maven依赖信息文件:javax.servlet-api-4.0.0.pom; ...
本篇文章将聚焦于`javax.servlet-api-4.0.1.jar`这个jar包,它是Servlet API 4.0.1版本的实现,主要用于支持JSP和Servlet的开发,特别是针对自定义标签的使用。本文将详细介绍Servlet API 4.0.1的关键特性以及如何在...
javax.servlet-api-3.1.0.jar,处理找不到servlet JAR的问题
Servlet 线程安全问题 Servlet 线程安全问题是指在使用 Servlet 编程时,如果不注意多线程安全性问题,可能会导致难以发现的错误。Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常...
当你遇到“找不到javax.servlet.*”这样的错误时,通常是因为你的项目缺少了这个库,所以需要引入`javax.servlet.jar`来解决问题。 1. **Java Servlet简介** Java Servlet是Java平台上的一个标准,用于扩展服务器...
javax.servlet-api-***.jar中文文档.zip,java,javax.servlet-api-***.jar,javax.servlet,javax.servlet-api,***,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,javax,servlet,api,中文API文档,手册,开发...
Servlet-api-3.0.jar是Java Servlet API的第三版实现,它是开发Web应用程序的重要组成部分,特别是在基于Java的服务器端编程中。这个库包含了用于创建和管理HTTP服务端点的接口和类,允许开发者构建动态、交互式的...
jakarta.servlet-api-4.0.4.jar jakarta.servlet-api-4.0.4-javadoc.jar jakarta.servlet-api-4.0.4-sources.jar
thrift 生成的java包servlet-api-2.5.jar
javax.servlet.jsp-api-2.3.1.jar
在IT行业中,尤其是在Java Web开发领域,`javax.servlet-api`和`javax.el`库是至关重要的组件。这些库主要用于实现Servlet规范和表达式语言(EL)功能,它们为开发人员提供了与服务器交互以及处理HTTP请求的能力。...
<servlet-class>test1.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/test1/*</url-pattern> </servlet-mapping> </web-app> ``` - **...
【javax-servlet-api-3.0.1.jar】是一个重要的Java库,主要用于开发Servlet应用程序。Servlet是Java平台上的一个标准接口,它允许程序员创建能够处理HTTP请求的服务器端程序。这个JAR文件包含了Servlet API 3.0.1...
综上所述,"java-servlet物流管理-成功.zip"文件中的内容可能涵盖了一系列Java Servlet相关的开发和实现细节,包括Servlet的基本使用、HTTP请求处理、MVC架构、数据库交互、会话管理以及系统安全性和性能优化等多个...
总的来说,理解和研究`servlet-api-src`中的`javax.servlet.Servlet`源码对于任何Java Web开发者来说都是一个重要的学习步骤。它不仅可以帮助我们深入理解Servlet的工作原理,还可以提升我们在实际项目中的开发效率...