为了账号安全,请及时绑定邮箱和手机立即绑定

HttpSession线程安全吗?设置/获取属性线程安全操作吗?

HttpSession线程安全吗?设置/获取属性线程安全操作吗?

郎朗坤 2019-10-08 10:41:19
另外,要设置的对象是否必须是线程安全的,以保证我们知道会话中存储的对象的状态是什么。另外,我正在网上阅读一些建议使用的内容:synchronized(session) {  session.setAttribute("abc", "abc");}这是一个有效的建议吗?
查看完整描述

3 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

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


从Java Ranch来看HttpSession如何不是线程安全的,这也可能会有所帮助。


查看完整回答
反对 回复 2019-10-08
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

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创建互斥体,但是必须有更好的方法。


查看完整回答
反对 回复 2019-10-08
?
莫回无

TA贡献1865条经验 获得超7个赞

在某些方面,这取决于您的客户端设计。

在您的Web设计中,您是否有机会让单个客户端使用同一HTTP会话拥有多个未完成的同时请求?除非您将单个HTTP会话绑定到多个套接字,否则这似乎很难做到。(aka,AJAX)没有这样做,就服务器而言,给定客户端的HTTP访问将是单线程的,这意味着单个会话实际上是线程安全的。

会话对象的同步将使应用程序更安全,以防将来的更改使Web应用程序能够同时发出多个请求,因此这不是一个坏主意。在现代Java实现中,同步并没有以前带来的高昂成本,尤其是在通常不争用同步的情况下。如果您的应用程序使用AJAX,这意味着您希望向Web服务器发送多个正在进行的同时请求,那么必须进行同步。


查看完整回答
反对 回复 2019-10-08
  • 3 回答
  • 0 关注
  • 754 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信