Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execution of `mappingFunction` in ConcurrentHashMap.computeIfAbsent and ConcurrentHashMap.computeIfPresent

I am trying to see actual Java documentation describing the behavior of how many times mappingFunction can be called when passed to ConcurrentHashMap.computeIfAbsent and ConcurrentHashMap.computeIfPresent methods.

The Javadoc of ConcurrentHashMap.computeIfAbsent seems pretty clear in saying that the mappingFunction will be executed at most once:

Javadoc for ConcurrentHashMap.computeIfAbsent

If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null. The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.

But the Javadoc for ConcurrentHashMap.computeIfPresent does not say anything about how many times mappingFunction can be executed:

Javadoc for ConcurrentHashMap.computeIfPresent

If the value for the specified key is present, attempts to compute a new mapping given the key and its current mapped value. The entire method invocation is performed atomically. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.

By looking at the source code they both look like that mappingFunction will be executed at most once. But I would really like to see actual documentation guaranteeing that behavior.

Is there such a documentation?

like image 885
tsolakp Avatar asked Oct 17 '22 23:10

tsolakp


1 Answers

In the documentation for ConcurrentMap#computeIfPresent, we see the following:

The default implementation is equivalent to performing the following steps for this map:

for (V oldValue; (oldValue = map.get(key)) != null; ) {
    V newValue = remappingFunction.apply(key, oldValue);
    if ((newValue == null)
        ? map.remove(key, oldValue)
        : map.replace(key, oldValue, newValue))
     return newValue;
 }
 return null;

Even though the documentation doesn't explicitly say that the remapping function will only be executed once, the equivalent code that the documentation provides makes that clear.

Note: Keep in mind that:

When multiple threads attempt updates, map operations and the remapping function may be called multiple times.

(emphasis mine)

like image 79
Jacob G. Avatar answered Nov 15 '22 06:11

Jacob G.