Servlet的线程安全

  在一般情况下,Servlet容器只创建一个实例,如果有多个客户请求同时访问这个Servlet,会采用多线程来访问这一个Servlet。在这种情况下,就会有线程安全问题。

  比如,定义一个Servlet的类变量user,然后在doPost或者doGet里处理的话,当线程转换时就会出现很怪的情况。如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
 
@WebServlet("/ServletSecurity")
public class ServletSecurity extends HttpServlet {
    private static final long serialVersionUID = -1841665725196115690L;
 
    private String user;
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        this.user = request.getParameter("user");
        PrintWriter out = response.getWriter();
        out.println(this.user + ", Welcome.");
    }
}

  在上面这段代码里,有些人认为没有把user变量设为静态变量就不会出现线程问题了。其实不是的,因为Servlet容器只建一个实例,在线程间切换时就会出问题。如A和B两个人同时登录时,A先执行,在this.user = request.getParameter("user");把user设为A;然后线程切换了,B把user设为B,执行完之后再执行A,就会输出B, Welcome。

  解决上面问题的方法就是,不要在Servlet定义可写的类变量,当然可写的静态变量就更不能定义了。

参考资料:孙鑫《Java Web开发详解——XML XSLT Servlet JSP深入剖析实例应用》第11章 开发线程安全的Servlet

本文固定链接: http://yutuo.net/archives/e180c988fce8ae2c.html | 宇托的狗窝

该日志由 yutuo 于2012年01月22日发表在 Java 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Servlet的线程安全 | 宇托的狗窝
关键字: ,

Servlet的线程安全:等您坐沙发呢!

发表评论

*

快捷键:Ctrl+Enter