I already searched through some SO questions like this one, and this one, but no real conclusion could be made on my end. So, I'll lay it out:
I have the following nested map structure concept, intended for multi-threaded environment:
Map<Integer, HashMap<String, AtomicInteger>> bufferMap = new ConcurrentHashMap<Integer, HashMap<String, AtomicInteger>>(2);
This "buffer map" should basically stores some hourly counters (AtomicInteger
s), identified / accessed by specific String
keys. So, Integer
keys for the buffer map are actually hour numbers (0...23). I only ever intend to "buffer" current and pre-set the next hour. To that effect, there's a timer task that runs once an hour, and does a maintaining procedure - something like this:
private final Map<Integer, HashMap<String, AtomicInteger>> bufferMap;
...
private final java.util.Timer;
private final java.util.TimerTask task = new TimerTask() {
@Override
public void run() {
....
HashMap<String, AtomicInteger> counterMap = bufferMap.get(previousHour);
// now read internalMap's values, and "store/flush" them somewhere
// at this point no thread but this one should access previous hour data
initializeNextHourSlot(); // populate new map entry for the next hour with new AtomicInteger(0) values
bufferMap.remove(previousHour); // clear previous hour, as no longer needed
}
}
Now, multiple threads may randomly and/or in parallel access this structure, to increment counters in the following manner:
bufferMap.get(currentHour).get(stringKey).incrementAndGet();
As outer (buffer) map is actually modified by different (Timer
's) thread than the ones reading it, it was logical, I assume, to use ConcurrentHashMap
.
However, I have my doubts about the inner (counter) map... It will always be populated by the timer thread ahead of time (no other threads should access it for at least an hour), and will then be accessed (read only), as shown above, to increment counter values.
Is this a thread safe approach, or not? And if not, what could be an alternative suggested data structure (and/or approach) ?