Java: map of concurrently incremented counters

concurrency, counter, dictionary, java

Solution

What makes you think AtomicLong uses locks internally? That is not true, it's mostly built on CAS operations. My advice would be to implement it with AtomicLong and profile the implementation later. If (and only if) your counter will be a bottleneck, then consider replacing it with any other implementation.

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" - Donald Knuth

As of state persistence the simplest approach is to serialize your map:

ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(map);
objOut.close();

Problem

I need to implement a map of counters (like Map) in my application. However this structure is supposed to be accessed by several threads. It looks like `ConcurrentHashMap<Key, Long>` is not a proper solution, right? I thought about `ConcurrentHashMap<Key, AtomicLong>` instead. But there is a problem - requests for increment are not spread evenly. Few most popular Keys could have up to 95% of all increment requests to this data structure. As far as I understand this will lead to concurrent access to single `AtomicLong` instances and there many locks should occur which will somewhat decrease efficiency. Question 1: Is there any better solution - perhaps, better data type instead of `AtomicLong`, which allows short accumulation of increments or something like this? Question 2: I want to persist the structure to disk periodically (perhaps, every minute), and I want to persist its "actual" state (with all recent updates settled?) - what is most straightforward way for it?

Original source