Java – A thread-safe eventual consistency counter

A thread-safe eventual consistency counter… here is a solution to the problem.

A thread-safe eventual consistency counter

I have a highly concurrent code that should be able to increment/decrement several counters at the same time and read values. I don’t need to have an exact value on every read, so it may end up consistent. My main goal is that writes are non-blocking and don’t require wait time, basically several threads want to increment the same counter, calling some increment function instead of waiting for it to be processed.
However, I have a hard time coming up with a way to make such a counter.

I’m thinking about using ConcurrentLinkedQueue<Boolean> Add an element to the queue and have another thread pop the element and calculate the increment\decrement. However, it’s not BlockingQueue, so I have to create a thread that constantly tries to poll the queue, and having one thread completely dedicated to this task feels like a huge waste. Just asking size() is not an option, because ConcurrentLinkedQueue The operation is not constant time, and each call has to traverse the entire queue, which would be a crazy waste of time.

I

also looked at AtomicInteger but only the delay set operation, no delay delta, incrementAndGet If I understand correctly, it will result in lock-based delta read behavior, which is definitely not what I need.

Is using ConcurrentLinkedQueue<Boolean> and a dedicated polling thread the only option for my eventual consensus counter? Especially considering that I don’t know how many threads will try to write and read this counter at any given moment, these are generated dynamically.

Solution

Sounds like java.util.concurrent.LongAdder might be what you’re looking for:

This class is usually preferable to AtomicLong when multiple threads update a common sum that is used for purposes such as collecting statistics, not for fine-grained synchronization control . Under low update contention, the two classes have similar characteristics. But under high contention, expected throughput of this class is significantly higher, at the expense of higher space consumption.

Related Problems and Solutions