src/share/classes/java/util/concurrent/ConcurrentMap.java

Print this page
rev 8834 : 8029055: Map.merge and ConcurrentMap.merge @implSpec is not correct in case of non-existing key-value pair or a null value entry
Reviewed-by: duke


 456                 }
 457             }
 458         }
 459     }
 460 
 461 
 462     /**
 463      * {@inheritDoc}
 464      *
 465      * @implSpec
 466      * The default implementation is equivalent to performing the
 467      * following steps for this {@code map}, then returning the
 468      * current value or {@code null} if absent:
 469      *
 470      * <pre> {@code
 471      * V oldValue = map.get(key);
 472      * V newValue = (oldValue == null) ? value :
 473      *              remappingFunction.apply(oldValue, value);
 474      * if (newValue == null)
 475      *     map.remove(key);
 476      * else if (oldValue == null)
 477      *     map.remove(key);
 478      * else
 479      *     map.put(key, newValue);
 480      * }</pre>
 481      *
 482      * <p>The default implementation may retry these steps when multiple
 483      * threads attempt updates including potentially calling the remapping
 484      * function multiple times.
 485      *
 486      * <p>This implementation assumes that the ConcurrentMap cannot contain null
 487      * values and {@code get()} returning null unambiguously means the key is
 488      * absent. Implementations which support null values <strong>must</strong>
 489      * override this default implementation.
 490      *
 491      * @throws UnsupportedOperationException {@inheritDoc}
 492      * @throws ClassCastException {@inheritDoc}
 493      * @throws NullPointerException {@inheritDoc}
 494      * @since 1.8
 495      */
 496     @Override
 497     default V merge(K key, V value,




 456                 }
 457             }
 458         }
 459     }
 460 
 461 
 462     /**
 463      * {@inheritDoc}
 464      *
 465      * @implSpec
 466      * The default implementation is equivalent to performing the
 467      * following steps for this {@code map}, then returning the
 468      * current value or {@code null} if absent:
 469      *
 470      * <pre> {@code
 471      * V oldValue = map.get(key);
 472      * V newValue = (oldValue == null) ? value :
 473      *              remappingFunction.apply(oldValue, value);
 474      * if (newValue == null)
 475      *     map.remove(key);


 476      * else
 477      *     map.put(key, newValue);
 478      * }</pre>
 479      *
 480      * <p>The default implementation may retry these steps when multiple
 481      * threads attempt updates including potentially calling the remapping
 482      * function multiple times.
 483      *
 484      * <p>This implementation assumes that the ConcurrentMap cannot contain null
 485      * values and {@code get()} returning null unambiguously means the key is
 486      * absent. Implementations which support null values <strong>must</strong>
 487      * override this default implementation.
 488      *
 489      * @throws UnsupportedOperationException {@inheritDoc}
 490      * @throws ClassCastException {@inheritDoc}
 491      * @throws NullPointerException {@inheritDoc}
 492      * @since 1.8
 493      */
 494     @Override
 495     default V merge(K key, V value,