Inside an application scoped bean, we have a hashmap that holds some counters for each user (just transient, not saved anywhere) each user is represented by it's own sub-hashmap:
Map<String, Map<String, Object>> userValues = new HashMap<String, Map<String, Object>>();
for instance:
application.getUserValues().get(user.id).put("lastAction", new Date());
Every Sub-Hash-Map is initialized empty (single-threaded) during startup. Each Sub-Hash-Map is guaranteed to ONLY be modified ("put", never remove) and not beein replaced.
Write Access on the Sub-Hash-Maps is guaranteed to happen only by a single thread at any time, but as the example above shows, there could be 2 threads modifying two different sub-maps at the same time)
We are not using a SessionScope, because some of the information needs to be exposed to other sessions as well (i.e. the Teamlead should be able to see the values)
Until now, there never have been Concurrency-Issues, but Concurrency is always hard to "test" properly as it mainly depends on the overall system-load and actions beeing performed around the same time.
Following this thread: Is ConcurrentHashMap.get() guaranteed to see a previous ConcurrentHashMap.put() by different thread? I assume, that using Concurrent Hashmaps for the inner hashmap would perfectly ensure that there are no problems using put
and get
on the same map at the same time from different threads.
So it would be better to use Map<String, ConcurrentHashMap<String, Object>>
right?
Would it also be required to use a ConcurrentHashmap for the "outer" map? That map never changes, only operation on that one will be get()
.