当前位置:  开发笔记 > 编程语言 > 正文

HttpSession线程是否安全,是否设置/获取属性线程安全操作?

如何解决《HttpSession线程是否安全,是否设置/获取属性线程安全操作?》经验,为你挑选了2个好方法。

此外,正在设置的对象是否必须是线程安全的,以保证我们知道会话中存储的对象的状态是什么.

此外,我正在网上阅读一些建议使用:

synchronized(session) {
  session.setAttribute("abc", "abc");
}

这是一个有效的建议吗?



1> McDowell..:

Servlet 2.5规范:

执行请求线程的多个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);

保证是安全的:

// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
  Integer n = (Integer) session.getAttribute("foo");
  session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

我已经看到了最后提出的方法(包括在J2EE书籍中),但不保证它可以通过Servlet规范工作.您可以使用会话ID创建互斥锁,但必须有更好的方法.


顺便说一句 - 对于"为什么会话对象上的同步可能不起作用"这一问题的正确答案是请求包装.无法保证您可能得到什么对象.任何人都可以创建请求包装器,它将返回自己的HttpSession实现(例如,一个日志记录或控制set/get,...).

2> duffymo..:

不,它们不是线程安全的,根据IBM - Java理论和实践:所有有状态的Web应用程序都被破坏了吗?.你需要同步.

HttpSession如何不受Java Ranch的线程安全可能也有帮助.

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有