一.作用域为servletContext的属性不是线程安全的,因为作用域为context的数据可供整个app访问,不同的线程,不同的selverlet可以同时访问同一个数据。
解决线程安全的方法是:锁住servletContext对象
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
out.println(“test context attributes<br>”);
synchronized(getServletContext()) {
getServletContext().setAttribute(“foo”, “22”);
getServletContext().setAttribute(“bar”, “42”);
out.println(getServletContext().getAttribute(“foo”));
out.println(getServletContext().getAttribute(“bar”));
}
}
二.作用域为session的属性是非线程安全的,虽然一个会话只能有一个session,但是一个客户同时打开2个浏览器窗口时,session不是线程安全的。
解决线程安全的方法是:锁住session对象
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
out.println(“test session attributes<br>”);
HttpSession session = request.getSession();
synchronized(session) {
session.setAttribute(“foo”, “22”);
session.setAttribute(“bar”, “42”);
out.println(session.getAttribute(“foo”));
out.println(session.getAttribute(“bar”));
}
}
三.servlet类的实例变量是非线程安全的
因为一个servlet可能有多个线程同时访问实例变量
可以为该servlet实现单线程接口,这样可以线程安全,但是实际开发没人这样做,因为这样做影响并发性。
那么,一般是在servlet类中尽量不写实例变量,即在jsp中不写<%! %>
四.只有请求属性(request作用域属性)和局部变量是线程安全的。