如何在java的httpsession中安全地存储hashmap

如何在java的httpsession中安全地存储hashmap,java,servlets,concurrenthashmap,httpsession,Java,Servlets,Concurrenthashmap,Httpsession,如果我在httpsession中存储一个并发hashmap,那么如何以线程安全的方式使用这个hashmap?通过使用hashmap,我指的是以线程安全的方式添加和从hashmap中检索 在获取/放入此hashmap时,我应该锁定哪个对象 这个代码好吗: private static final String SESSION_KEY_USER_IDENT = "CloudIdentityUserListMap"; private someSessionPopulateFunc() { f

如果我在httpsession中存储一个并发hashmap,那么如何以线程安全的方式使用这个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上的锁?

来自Java Servlet规范3.0:

7.7.1螺纹问题

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

但是,HttpSession是一个哈希映射。很难理解为什么需要嵌套的


而且ConcurrentHashMap也已经是线程安全的。

更重要的是,谁是这个映射的并发用户?您真的希望同一会话有多个并发使用吗?在HttpSession中存储ConcurrentHashMap的原因是什么?这方面的用例是什么?整个构造只能在单个JVM或单个web上下文中工作。使用会话id的内部对象是脆弱的。关于你的问题,如果你需要从散列图中阅读。答案是否定的。这里有趣的是如何访问值/在哪个上下文中,以及当会话被序列化/反序列化时会发生什么。想想你是否真的需要这个结构,为什么,以及是否可以用另一种方式来解决它。所以对于我的用例,我只填充一次hashmap,然后从中读取。。。一旦填充,hashmap无论如何都不会被填充。。。我担心的是,当填充hashmap时,可能会出现一个竞争条件,因为来自同一用户的两个或多个请求将访问同一个会话对象……同一用户将同时在两个不同的页面上?@EJP这并不一定意味着这些页面是不同的,只要想想一个页面的web应用程序就可以了我有一个复杂的数据结构,它有一个hashmap。。。。我正在会话中存储此数据结构。。。。因为将它存储到会话将是线程安全的,所以我不担心它。。。。我担心的是以线程安全的方式操纵数据结构内部的映射……好吧,那么从映射读取可能不需要任何锁,但是在会话中存储映射时,我应该在会话中同步,然后再存储,对吗?否则,可能会有多个请求试图在会话中存储此映射……不,因为我已经引用了Servlet规范7.7.1。这里的一切都是线程安全的。你什么都不用做。谢谢,听起来不错;出于好奇,如果这个hashmap在另一个对象中,并且这个对象存储在会话中,那么会发生什么呢?在这种情况下,在使用映射执行任何操作时,我需要一个锁,对吗?因为servlet规范说开发人员需要使对会话中存储的对象的访问线程安全。。。对于这个用例,我应该使用sess.getHttpSession.getId.intern来锁定吗?正如前面提到的,由于各种原因,使用getId.intern是危险的。例如,见。为什么不使用像专用锁对象、信号量、队列或?