Roller中的会话安全违规

时间:2012-07-20 02:58:17

标签: java multithreading session concurrency atomicity

RollerSession包含以下代码:

public static RollerSession getRollerSession(HttpServletRequest request) {
    RollerSession rollerSession = null;
    HttpSession session = request.getSession(false);
    if (session != null) {
        rollerSession = (RollerSession)session.getAttribute(ROLLER_SESSION);
        if (rollerSession == null) {
            // HttpSession with no RollerSession?
            // Must be a session that was de-serialized from a previous run.
            rollerSession = new RollerSession();
            session.setAttribute(ROLLER_SESSION, rollerSession);
        }
      ....

我是并发问题的新手。这里似乎存在原子性违规,两个不同的线程可能同时更新setAttribute。是对的吗?可以通过两个线程共享会话,因为它是从请求中获取的吗?

1 个答案:

答案 0 :(得分:1)

是的,你是对的,更有可见性问题!根据{{​​3}}和IBM's post,get / set操作 NOT 线程安全。因此,如果您不希望应用程序中存在任何竞争条件,则应进行同步,但要小心放置同步的位置。

说明

执行请求线程的多个servlet可以同时具有对同一会话对象的活动访问权限。容器必须确保以线程安全的方式执行表示会话属性的内部数据结构的操作。开发人员负责线程安全访问属性对象本身。这将保护HttpSession对象内的属性集合免于并发访问,从而消除了应用程序导致该集合损坏的机会。

这是安全的:

// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);

这是安全:

HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);

- Java Ranch