Can java.util.concurrent.ConcurrentHashMap.putIfAbsent be in a synchronized block?

I'm trying to track the status of a race, and all the signs seem to point to ConcurrentHashMap.putIfAbsent() . Is it possible that if 2 threads call putIfAbsent() on an empty map with the same key that both can do their search to see that the key does not exist yet, so both threads then try to add it? For some reason, when I first started using putIfAbsent() , I didn't think the call would need to be synchronized. But now I don’t see how this can prevent both threads from adding their values ​​if the time was right. I could not reproduce this outside production.

thanks

+4
source share
2 answers

None of the operations for any parallel collection need synchronization.

It is by design and in fact the collection lock does not affect other operations. (If they are not locked), in this case it will make them slower.

Is it possible that if 2 threads calls putIfAbsent () on an empty map with the same key that both can do their search to see that the key does not exist yet, so both threads then try to add it?

Both can try, but only one will succeed. It is impossible for two threads to succeed.

For some reason, when I first started using putIfAbsent (), I did not think that the call needed to be synchronized.

This is not true.

But now I don’t see how this can prevent both threads from adding their values ​​if the time was right.

It performs the CAS operation in code, which means that only one operation can be successful, and the thread will know which one. The CAS operation does not require locking, because it uses a basic assembly instruction to execute it. In fact, you usually use locking using the CAS operation, and not vice versa.

+9
source

Is it possible that if 2 threads call putIfAbsent on an empty card with the same key that both can do their search to see that the key does not exist yet, so both threads then try to add it?

Doesn't match putIfAbsent() documentation:

If the specified key is not yet associated with the value, match it with the specified value. It is equivalent

 if (!map.containsKey(key)) return map.put(key, value); else return map.get(key); 

except that the action is atomic .

This means that for both threads it is not possible to try to insert a key-value pair.

+3
source

Source: https://habr.com/ru/post/1497946/


All Articles