Firstly, how predictable is the outer Map's key string value? If that's all predictable at design time, I would rather turn that into an Enum and uses an EnumMap to hold the outer Map. The same applies for the inner map, too. In that case your question turns into
EnumMap<Enum, EnumMap<Enum, List<POJO>>>
and is perfectly resolved.
Secondly, since you are using a map of map structure and using in an env where performance matters, I would assume the number of keys in the outer map << the number of total POJOs inside the entire structure. That's to say, the chance you add a new submap to the whole structure is very small. In this case a ReadWriteLock is best on the outer Map; For the inner map you could consider either ReadWriteLock or ConcurrentHashMap.
There are 3 major design considerations for the ConcurrentHashMap:
- That it generates a lot of temp objects. So if your application is GC-sensitive you want to limit its usage.
- That it allows maximum 16 concurrent threads operating it by default - but this is unlikely to be a concern.
- That it's size() isn't constant time.
I would usually apply ReadWrite lock pattern or even atomic variable based implementation mainly when 1. turns out to be a problem. Otherwise I think ConcurrentHashMap does fine in most of circumstances.
Also, note that in the latest implementation of JDK, the Read/Write priority changed for the ReadWriteLock. If my memory is correct it seems to favor read operation than write; so in case you have too many reads your write thread might got thread starvation. In that case you might want your own read/write implementation.