We collect some statistics using AtomicLongs. Some users are seeing contention on these and have suggested using LongAdder instead. However I see no way to calculate the maximum value as we are currently doing with the Atomic:
AtomicLong _current, _total, _max;
...
void add(long delta)
{
long current = _current.addAndGet(delta);
if (delta>0)
{
_total.addAndGet(delta);
long max = _max.get();
while (current > max)
{
if (_max.compareAndSet(max, current))
break;
max = _max.get();
}
}
So I think we can replace _total
easily enough with a LongAdder
, but because we do _current.addAndGet(delta)
that will not work well for a LongAdder
, nor can we do cas operation for the `_max' value.
Are there any good algorithms for collecting such statistics based on LongAdder
or similar scalable lock free constructs?
Actually, whiles I'm asking, our stats typically update 6 to 10 AtomicLongs. If we are seeing contention anyway, could it be possibly be better to just grab a lock and update 6 to 10 normal longs?
You don't want LongAdder
, but LongAccumulator
here: you want new LongAccumulator(Math::max, Long.MIN_VALUE)
, which does the right thing here. LongAdder
is a special case of LongAccumulator
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With