I'm having a problem where an AtomicInteger value is being unexpectedly set to zero and throwing an ArithmeticExpection ( / by zero). This is happening in a multi-threaded environment.
I wrote a simple method that "cleans" some entries of a ConcurrentHashMap object, if the respective value for a key is an empty queue.
Here is the method:
public void cleanUp(ConcurrentHashMap<String, BlockingQueue<E>> map) {
synchronize(map){
int countRemovals = 0;
for (Map.Entry<String, BlockingQueue<E>> entry : map.entrySet()) {
if (entry.getValue().isEmpty()) {
map.remove(entry.getKey());
countRemovals++;
}
}
if (((countRemovals / keysSizeCapForCleanup.get()) * 100) <= ACCEPTABLE_CLEANUP_PERCENTAGE) {
int aux = keysSizeCapForCleanup.get();
keysSizeCapForCleanup.compareAndSet(aux, aux * 2);
}
}
}
As is visible in the method I then do some logic to determine if the current cap needs to be higher. Problem is that then I do any call to keysSizeCapForCleanup.get(), I get an ArithmeticExpection on that line.
The variable is initialised in the class constructor, as follows:
public class EventsProducerConsumer {
...
public AtomicInteger keysSizeCapForCleanup;
...
public EventsProducerConsumer(int cleanUpCap) {
this.keysSizeCapForCleanup = new AtomicInteger(cleanUpCap);
if (cleanUpCap <= 0) {
throw new IllegalArgumentException("Initial cap must be higher than zero");
}
}
And the variable is never changed anywhere else. But is read using get() in other parts of the class.
Any idea why this could be happening?
Thanks!