多个用户会同时访问一个页面,所以Java web服务器通常是多线程的。对于某个servlet,同时有多个请求时,该Servlet会在多个线程中被执行,必须考虑线程安全。
Servlet线程安全要注意的地方:
- servlet
service()
方法通常应避免使用成员变量、静态变量,如要使用需作互斥 - 局部变量一般是线程安全的,但要注意局部变量指向同一个对象的情况
请求(HttpServletRequest
)和响应(HttpServletResponse
)对象是线程安全的,每次请求都会创建新实例。
servlet线程安全示意图如下,红色框标出的成员变量与静态变量,service()
方法在使用时应注意线程安全。
其他要考虑线程安全的共享资源
凡是要在多个线程中共享的资源,都必须考虑线程安全。除了Servlet类(或子类)本身的成员变量和静态变量,如果service()
方法使用了其他类中的静态变量或成员变量,也必须考虑线程安全。
示例
下面的代码示例展示了必须注意线程安全的地方。
public class MyHttpServlet extends HttpServlet {
// 静态变量,线程不安全
protected static List list = new ArrayList();
// 成员变量,线程不安全
protected Map map = new HashMap();
protected void doGet( HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// 其他类的静态变量,线程不安全
SomeClass.getSomeStaticVariable();
// 局部变量,线程安全
Set set = new HashSet();
}
}