【发布时间】:2017-12-20 20:23:43
【问题描述】:
如果我在 httpsession 中存储并发 hashmap,那么如何以线程安全的方式使用这个 hashmap?使用 hashmap 是指以线程安全的方式添加和检索 hashmap。
在获取/放入此哈希图时我应该锁定什么对象?
这段代码好吗:
private static final String SESSION_KEY_USER_IDENT = "CloudIdentityUserListMap";
private someSessionPopulateFunc()
{
final Object lock = sess.getHttpSession().getId().intern();
ConcurrentHashMap<String, List<User>> cloudIdentityUserListMap;
if (sess.getAttribute(SESSION_KEY_USER_IDENT) != null) {
synchronized (lock) {
cloudIdentityUserListMap = (ConcurrentHashMap<String, List<User>>) sess.getAttribute(SESSION_KEY_USER_IDENT);
}
} else {
cloudIdentityUserListMap = new ConcurrentHashMap<String, List<User>>();
synchronized (lock) {
sess.setAttribute (SESSION_KEY_USER_IDENT, cloudIdentityUserListMap);
}
}
cloudIdentityUserListMap.putIfAbsent(cloudIdentity,users);
}
在从这个 concurrenthashmap 读取值时,我是否需要再次获取 sess.getHttpSession().getId().intern() 的锁定?
【问题讨论】:
-
更重要的是,这张地图的并发用户是谁?您真的期望同一个会话有多个并发使用吗?
-
将
ConcurrentHashMap存储在HttpSession中的原因是什么?那有什么用例?整个构造只能在单个 JVM 或单个 Web 上下文中工作。使用 session id 的内部对象是脆弱的。关于您的问题,如果您需要从哈希图中查找。答案是不。这里有趣的是您如何访问值/在哪个上下文中以及当会话被序列化/反序列化时会发生什么。想想你是否真的需要这个结构,为什么以及是否可以通过其他方式解决。 -
所以对于我的用例,我将只填充一次哈希图,然后从中读取...一旦填充了哈希图,无论如何都不会被操纵...我担心的是,虽然填充哈希图可能存在竞争条件,因为来自同一用户的 2 个或更多请求将访问同一个会话对象...
-
同一个用户会同时出现在两个不同的页面上?
-
@EJP 这并不一定意味着这些是不同的页面,只是想一个单页 Web 应用程序,它对服务器端进行大量调用。
标签: java servlets concurrenthashmap httpsession