Beercola
Beercola

Reputation: 1

Is it strictly necessary to use atomic integer inside a compute block?

My doubt is simple. According to other posts this is not thread safe because of the reading+write operation count++. But a compute as far as I know, blocks the entire sector for that key inside the map. So it's impossible that two threads performs this operation at the same time. Why should I use atomic integer or any other concurrent object?

Key can be a profile and the counter it's just a counter for something that can be numeric. Posts, messages, likes... The structure is a ConcurrentHashMap<Key,Integer>.

   counters.compute(key, (key, counter) -> {
        if (counter == null) {
            return 1;
        } else {
            return count++;
        }
    });

I didn't find any issue executing threads in some tests. But still I don't understand why should I use atomic integer.

Upvotes: -4

Views: 98

Answers (1)

Thomas Kl&#228;ger
Thomas Kl&#228;ger

Reputation: 21640

Your example is flawed because return count++; increments count but returns the previous value - i.e. it never counts up. That line should be return count + 1;:

counters.compute(key, (k, count) -> {
    if (count == null) {
        return 1;
    } else {
        return count+1;
    }
});

Note that this usage of ConcurrentHashMap.compute() (with Integer as value) is inherently thread safe:

  • the compute() function is atomically executed for a specific key - i.e. no other thread can call compute() for the same key at the same time and therefore you cannot loose an update.
  • concurrent get() calls either see the old or the new value depending on the exact timing but (since Integer is immutable) they cannot corrupt the count.

Using the merge() method leads to an even simpler solution (thanks to David Conrad for the hint):

counters.merge(key, 1, Math::addExact);

This throws an ArithmeticException if the counter would overflow. If you want to allow the counter to overflow you can use

counters.merge(key, 1, Integer::sum);

Upvotes: 3

Related Questions