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.