Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8232652

Clarify that ConcurrentHashMap compute methods mapping functions execute at most once

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 14
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      Just clarifying existing behavior
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      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) {

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                martin Martin Buchholz
                Reporter:
                martin Martin Buchholz
                Reviewed By:
                Doug Lea
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: