-2

If I store a concurrent hashmap in a httpsession then how can I use this hashmap in a threadsafe manner? by using the hashmap I mean adding and retrieving from the hashmap in a threadsafe manner.

what object should I lock on while getitng/putting in this hashmap?

is this code good:

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);
}

Will I need to acquire lock on sess.getHttpSession().getId().intern() again while reading value from this concurrenthashmap?

Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • 1
    More to the point, who are the concurrent users of this map? Are you really expecting multiple concurrent uses of the same session? – user207421 Jul 16 '17 at 04:33
  • What's the reason for storing a `ConcurrentHashMap` in a `HttpSession`? What's the use case for that? The whole construct only may work on a single JVM or in a single web context. Using the internal object of the session id is fragile. About your question if you need a look for reading from the hash map. The answer is no. Interesting here is how you access the values / in which context and how what happens when the session gets serialialised / deserialised. Think about if you really need this construct and why and whether it can be solved in another way. – andih Jul 16 '17 at 04:37
  • so for my usecase, i'd be populating the hashmap only once and then just read from it... once populated the hashmap won't be manupulated in anyway... my concern is that while populating the hashmap there maybe a racecondition as 2 or more requests from same user will be accessing the same session object... – Manu Mehrotra Jul 16 '17 at 07:37
  • The same user will be on two different pages at the same time? – user207421 Jul 16 '17 at 07:40
  • @EJP it's does not necessarily mean to that these are different pages just think of a single page web application which does a lot of calls to the server side. – andih Jul 16 '17 at 08:51
  • 2 or more ajax calls.... does that ring a bell?... I am surprised that the question is downvoted! – Manu Mehrotra Jul 16 '17 at 17:59

1 Answers1

0

From Java Servlet Specification 3.0:

7.7.1 Threading Issues

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 thread safe manner. The Developer has the responsibility for thread safe 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.

However an HttpSession is a hash map. Hard to see why you would need a nested one.

And a ConcurrentHashMap is also already thread-safe.

Community
  • 1
  • 1
user207421
  • 305,947
  • 44
  • 307
  • 483
  • I have a complex datastructure which has a hashmap.... I am storing this datastructure in the session.... since storing it to the session will be threadsafe, I am not worried about it.... what I am worried about is manipulating the map inside the datastructure in a threadsafe way.... – Manu Mehrotra Jul 16 '17 at 07:34
  • ok so for reading from the map maybe I don't need any locks but while storing the map in the session, I should be synchronizing on session before storing right? else there can be more than one requests which might try to store this map on the session... – Manu Mehrotra Jul 16 '17 at 07:49
  • No, because of the Servlet Specification #7.7.1 which I have already quoted. Everything here is thread-safe. You don't have to do anything. – user207421 Jul 16 '17 at 07:55
  • thanks, that sounds right; just out of curiosity, what happens if this hashmap is in another object and this object is stored in session, in this case while doing anything with the map i'd need a lock right? since servlet specification says that developers need to make access to the object stored in session thread safe... for this use case should I use sess.getHttpSession().getId().intern() to lock on? – Manu Mehrotra Jul 16 '17 at 08:11
  • As already mentioned using `getId().intern()` is dangerous, for various reasons. See for example [here](https://stackoverflow.com/a/349774/1317117). Why not using something that definitely works like a dedicated lock object or a semaphore or a queue or ... ? – andih Jul 16 '17 at 08:50
  • You would need a lock ***why?*** A `ConcurrentHashMap` is thread safe no matter where you put it. – user207421 Jul 16 '17 at 10:39
  • @andih how about synchronizing on http session object itself? – Manu Mehrotra Jul 16 '17 at 18:02
  • @ManuMehrotra No, the session object itself is also not recommended to be used as lock object. See [here](https://stackoverflow.com/a/9802428/1317117). Also have a look at the other answers and the comments. – andih Jul 16 '17 at 19:07
  • @ManuMehrotra To repeat the first thing I asked you, synchronize *why*? You don't need to synchronize on a thread-safe object. – user207421 Jul 17 '17 at 00:54
  • I am not synchronizing on threadsafe object... sess is an object stored in HttpSession which has a concurrenthashmap... I am synchronizing on sess before storing the map in it... – Manu Mehrotra Jul 18 '17 at 21:48