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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值