`

HttpSession.setAttribute ServletContext.setAttribute是否线程安全

 
阅读更多
查阅了网上的一些帖子和spec等资料,总结多个帖子中的观点:
HttpSession和ServletContext的api doc中没有明确说明这些get/setAttribute方法是否线程安全。

Servlet 2.5 spec中提到(可以参见servlet-2_5-mrel2-spec.pdf):
Multiple servlets executing request threads may have active access to the same session object at the same time. The container must ensure that manipulation of internal data structures representing the session attributes is performed in a threadsafe manner. The Developer has the responsibility for threadsafe access to the attribute objects themselves. This will protect the attribute collection inside the HttpSession object from concurrent access, eliminating the opportunity for an application to cause that collection to become corrupted.

因此http://www.javamex.com/tutorials/servlets/session_synchronization.shtml这篇帖子中说的正确:
1. session.set/getAttribute(), application.set/getAttribute()单个调用是线程安全的。容器开发商需要保证其实现中内部所用的数据结构在一次get/set操作中线程安全。这一点查看tomcat5.5.35的源码也可以证实:
org.apache.catalina.session.StandardSession类用的是Hashtable();
org.apache.catalina.core.ApplicationContext类中用的是HashMap,但在其上的put和get操作都事先synchronize了这个hashmap object。
(但一些较早的容器实现确实存在这些方面的bug)

2. if you want to combine multiple sets/gets into an atomic operation, then you need explicit synchronization. 可以:
(1)同步session:
HttpSession sess = req.getSession(true);
synchronized (sess) {
  sess.setAttribute("USERID", id);
  sess.setAttribute("USERNAME", username);
  ...
}
(2)如果是java 5及以上,可以用一个immutable object来封装具体的数据,然后直接setAttribut(该immutable object);
(3)可以lock一个static变量:
synchronized (lock) {
  sess.setAttribute("USERID", id);
  sess.setAttribute("USERNAME", username);
  ...
}
其他地方用到这些属性的时候也要先synchronized (lock), 而如果用的是其他不相关的属性,则不需要lock。但这样做的坏处是不同的session如果操作这些属性也会互相竞争了。

其他相关的帖子链接:
http://stackoverflow.com/questions/616601/is-httpsession-thread-safe-are-set-get-attribute-thread-safe-operations
http://stackoverflow.com/questions/5232846/request-get-setattribute-vs-this-getservletcontext-get-setattribute
https://issues.apache.org/bugzilla/show_bug.cgi?id=36541



分享到:
评论

相关推荐

    访问或添加三个范围的属性与获取Request-Session-ServletContext-Response对象.rar

    Session-ServletContext-Response对象”指的是在Java Web开发中,如何操作四个重要的请求处理对象:HttpServletRequest(Request)、HttpSession(Session)、ServletContext(通常称为应用上下文)和...

    sevlet生命周期,request web.xml 及ServletContext总结

    包括但不限于:`request.getAttribute()`和`setAttribute()`管理请求范围内的属性;`request.getHeader()`和`getHeaders()`获取HTTP头信息;`request.getParameterNames()`和`getParameterValues()`获取所有参数...

    java内置对象简介、四种属性范围的一些源代码

    这里主要涉及四个核心的内置对象:PageContext、HttpServletRequest、HttpSession和ServletContext,它们各自对应于四种不同的作用域。 1. PageContext对象:PageContext是JSP页面内部的数据存储区,它的生命周期仅...

    JavaBean 在jsp和serlvle中传递技术要点.doc

    ` 创建完实例后,需要根据需要将其放入不同的`scope`,如请求、会话或应用程序范围,这通常通过`request.setAttribute()`、`session.setAttribute()`或`servletContext.setAttribute()`方法实现。 二、JavaBean的...

    数据库测试test.sql

    HttpSession session = request.getSession(); // session.setAttribute("username",username); session.setAttribute("user",user); //response.sendRedirect("/myservlet2/admin/success.jsp"); //response....

    java程序员滴宝典

    - `isThreadSafe`:是否支持多线程,默认为true。 - `info`:设置JSP页面的信息。 - `errorPage`:设置错误页。 - `isErrorPage`:是否为错误页。 - `isELIgnored`:是否忽略表达式语言。 - `pageEncoding`:...

    javaServlet请求转发和重定向.pdf

    在 Web 应用程序中,还可以使用 HttpServletRequest 对象、HttpSession 对象、ServletContext 对象来存储数据。 例如,使用 HttpServletRequest 对象来存储数据: ```java request.setAttribute("score", score); ...

    EL与JSP相关内置对象

    - **session**:表示HttpSession对象,用于管理会话信息。 - **application**:表示ServletContext对象,用于访问应用范围的信息。 - **out**:表示JspWriter对象,用于生成页面输出。 - **config**:表示...

    JSP Chapter 4 JSP内置对象.ppt

    4. **application对象**:`javax.servlet.ServletContext`,它代表整个web应用程序的上下文,可以存储全局信息。`application.setAttribute()`和`application.getAttribute()`用于在整个应用范围内共享数据。 5. **...

    jsp.rar_jsp内置对象

    `HttpSession`接口的实例,用于维持客户端与服务器之间的会话状态。`session.getAttribute()`和`session.setAttribute()`用于存储和读取会话级别的数据,而`session.invalidate()`则可以结束会话。 5. **...

    JSPModel.rar_page

    `application` 对象,即`javax.servlet.ServletContext`,代表整个Web应用程序的上下文。它允许开发者在整个应用范围内共享数据,而不局限于单个用户会话。`application.getAttribute()`和`application....

    struts2.1文档

    在这个例子中,我们分别将数据存入了`ServletContext`(应用范围)、`HttpSession`(会话范围)和`HttpServletRequest`(请求范围)。 ### 方法二:通过ServletActionContext获取 `ServletActionContext`提供了对`...

    JSP_Servlet面试题[定义].pdf

    8. 从session中获取对象应使用`getAttribute`方法,正确答案是E:`HttpSession.getAttribute()`。 9. 在禁用cookie的情况下,保持客户端状态的技术: - B. HTTP Session - 可以使用基于URL的Session ID传递。 - C...

    JAVAweb开发14566PPT课件.ppt

    - `session.setAttribute(String name, Object value)`: 设置会话属性。 - `Object attribute = session.getAttribute(String name)`: 获取会话属性。 - `session.invalidate()`: 终止会话。 ### Cookie及其应用 ...

    JSP内置对象

    4. **应用对象 - application**:`ServletContext`的实例,保存在整个Web应用范围内的共享数据,所有用户都可访问。常用方法包括`application.setAttribute()`和`application.getAttribute()`,可以实现全局计时器等...

    javaee试验二Servlet程序设计知识.pdf

    7. 通过ServletContext访问外部资源,处理页面跳转。 8. 编写过滤器,检查登录状态并阻止非法访问。 9. 使用ServletContextListener监听器统计页面访问和在线用户信息。 代码示例(登录Servlet简化版): ```java ...

    JSP内部对象.ppt

    4. **application对象** - `javax.servlet.ServletContext` application对象代表整个Web应用程序的上下文,它在整个应用生命周期内都存在。开发者可以通过application对象来共享全局信息,如配置参数、计数器等。`...

    JSP内置对象使用说明.doc

    5.Session对象类:HttpSession Session对象用于保存用户的会话信息,可以在用户的整个会话期间保持数据。创建或获取session对象: ```java HttpSession session = request.getSession(); session.setAttribute(...

    JSP中的在线人数统计

    private ServletContext application = null; // 容器初始化时,向application中存放一个空的容器 public void contextInitialized(ServletContextEvent sce) { this.application = sce.getServletContext(); ...

    jsp内置对象

    5. **application** - `javax.servlet.ServletContext` - 共享数据的存储空间,对所有用户可见,用于应用程序级的数据共享。 6. **config** - `javax.servlet.ServletConfig` - 提供配置信息,如初始化参数等。 ...

Global site tag (gtag.js) - Google Analytics