简体   繁体   中英

ConcurrentHashMap atomic get, increment and replace

Is there an easy way to get, increment and replace an integer from a ConcurrentHashMap ?

ConcurrentHashMap<MyResource, AtomicInteger> map;

Let's say that every value has already been initialized like this:

map.get(i) = new AtomicInteger(0);

and that we do not add any new keys.

How can I make a get, increment and replace atomic (and thread safe)?

Something like this, should not work:

map.get(myResourceKey).incrementAndGet();

Because 2 threads could get the same integer before incrementing it right?

The map is keeping track of how many threads are using a certain resource. And I want something to happen only when a resource is not used (counter = 0).

You can use compute to perform atomic operations like the one you're asking for. The compute method will return the incremented value or 1 if it's the first call.

Map<MyResource, Integer> map = new ConcurrentHashMap<>();

map.compute(resourceKey, (k, v) -> v == null ? 1 : v + 1);

The AtomicInteger will work fine with multiple threads, that's its purpose. So if the map doesn't change, you're fine.

Problems will occur if several threads try to modify the map at the same time, for example two threads adding each their own AtomicInteger. In this case, synchronize the map itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM