Shared variable with unexpected value, throwing ArithmeticException divide by zero. (Java Concurrency)

Viewed 26

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!

0 Answers
Related