最新消息:发现真没时间折腾VPS,最近又换了个空间。呵呵

Servlet的线程安全

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

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

Java
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

转载请注明:宇托的狗窝 » Servlet的线程安全

发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址