I have a Counter class that stores value as AtomicInteger. That class should be thread safe. I have method boolean consume(int number)
that should decrement counter and return true
if counter >= number
, and should not change counter and return false
if counter < number
class Counter {
AtomicInteger counter = new AtomicInteger(initialValue);
boolean consume(int number) {
counter.accumulateAndGet(number, (prev, next) -> {
if (number <= prev) {
return prev - number;
} else {
// not modify the previous number;
return prev;
}
});
return ???
}
}
And I don't know if the function applied or not. I found the following solution
boolean consume(int number) {
AtomicBoolean result = new AtomicBoolean(false);
counter.accumulateAndGet(number, (prev, next) -> {
if (number <= prev) {
result.set(true);
return prev - number;
// function applied
} else {
result.set(false);
// not modify the previous number;
return prev;
}
});
return result.get();
}
but javadoc of accumulateAndGet
sais:
The function should be side-effect-free, since it may be re-applied when attempted updates fail due to contention among threads.
So, my solution has side effects. Is it safe to use? If not, how can I get the same result?