Servlet默认是线程不安全的!
Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。
当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。
当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。
Servlet容器会自动使用线程池等技术来支持系统的运行。
当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。
所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。
下面举一个例子来说明,为什么Servlet是线程不安全的。
public class MyServlet extends HttpServlet{ String message; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { message = req.getParameter("message"); PrintWriter out = resp.getWriter(); //故意延时5秒钟,使得下一次请求过来的时候,message的值还没有返回就被覆盖了 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } out.write(message); out.flush(); out.close(); } }
打开两个浏览器,分别访问:
http://localhost:8080/web/hello?message=jack
http://localhost:8080/web/hello?message=rose
因为有5秒的延时,所以可能就会出现第一个Servlet还没返回呢,第二个Servlet就进来了。于是,把message的值给冲掉了。如下图
石锤了,Servlet是线程不安全的。