AtomicInteger Map

I want to implement a general object for calculating statistics on operations. The state of the objects will be represented by Map<String,AtomicInteger> (the key is the name of the operation, value is the number of times the operation was performed). I will fix that I can choose the implementation of HashMap<String,AtomicInteger> and not use any synchronization for it to receive values ​​from it, since AtomicInteger has a variable field value below it.

Example code that adds and increases execution statistics:

 import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; public final class Stats { private final Map<String, AtomicInteger> statistics = new HashMap<String, AtomicInteger>(); public int increment(String operationName) { if (!statistics.containsKey(operationName)) { synchronized (statistics) { if (!statistics.containsKey(operationName)) statistics.put(operationName, new AtomicInteger(0)); } } return statistics.get(operationName).getAndIncrement(); } public int getOpStats(String operationName) { if (!statistics.containsKey(operationName)) { return 0; } return statistics.get(operationName).get(); } } 
+6
source share
1 answer

If you want to be thread safe with respect to counter initialization, you should use ConcurrentHashMap and always start and increment counters as follows:

 themap.putIfAbsent("the name", new AtomicInteger(0)); themap.get("the name").incrementAndGet(); 

You can also make sure that you initialize all the counters used before the start, and just use any collection you like. The simple AtomicInteger[] -array is much faster, given that you know where to look, a HashTable can be a little faster than a HashMap .

If you know in advance which counters you have, you can also determine the java enum all the counter names and use EnumMap<YourCountersEnum, AtomicInteger> . This will likely result in search results being close to AtomicInteger[] -array searches.

+3
source

All Articles