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线程不安全吗?_java

石锤了,Servlet是线程不安全的。