-
CSR
-
Resolution: Approved
-
P3
-
None
-
behavioral
-
minimal
-
Just clarifying existing behavior
-
Java API
-
SE
Summary
Clarify that ConcurrentHashMap compute methods mapping functions execute at most once
Problem
The ConcurrentHashMap compute* methods are insufficiently clear
Solution
Clarify mutual exclusion behavior of mapping methods.
Specification
@@ -1656,33 +1656,36 @@
/**
* 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 {@code 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.
+ * method invocation is performed atomically. The supplied
+ * function is invoked exactly once per invocation of this method
+ * if the key is absent, else not at all. 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.
+ *
+ * <p>The mapping function must not modify this map during computation.
*
* @param key key with which the specified value is to be associated
* @param mappingFunction the function to compute a value
* @return the current (existing or computed) value associated with
* the specified key, or null if the computed value is null
* @throws NullPointerException if the specified key or mappingFunction
* is null
* @throws IllegalStateException if the computation detectably
* attempts a recursive update to this map that would
* otherwise never complete
* @throws RuntimeException or Error if the mappingFunction does so,
* in which case the mapping is left unestablished
*/
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
@@ -1767,32 +1770,35 @@
/**
* 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.
+ * The supplied function is invoked exactly once per invocation of
+ * this method if the key is present, else not at all. 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.
+ *
+ * <p>The remapping function must not modify this map during computation.
*
* @param key key with which a value may be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key or remappingFunction
* is null
* @throws IllegalStateException if the computation detectably
* attempts a recursive update to this map that would
* otherwise never complete
* @throws RuntimeException or Error if the remappingFunction does so,
* in which case the mapping is unchanged
*/
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (key == null || remappingFunction == null)
@@ -1859,32 +1865,34 @@
/**
* Attempts to compute a mapping for the specified key and its
* current mapped value (or {@code null} if there is no current
* mapping). 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.
+ * The supplied function is invoked exactly once per invocation of
+ * this method. 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.
+ *
+ * <p>The remapping function must not modify this map during computation.
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key or remappingFunction
* is null
* @throws IllegalStateException if the computation detectably
* attempts a recursive update to this map that would
* otherwise never complete
* @throws RuntimeException or Error if the remappingFunction does so,
* in which case the mapping is unchanged
*/
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
- csr of
-
JDK-8231592 Clarify that ConcurrentHashMap compute methods mapping functions execute at most once
-
- Resolved
-