diff -r b73f38796859 -r 981893a47bec jdk/src/java.base/share/classes/java/util/Hashtable.java --- a/jdk/src/java.base/share/classes/java/util/Hashtable.java Thu Apr 02 11:54:33 2015 -0700 +++ b/jdk/src/java.base/share/classes/java/util/Hashtable.java Thu Apr 02 12:33:03 2015 -0700 @@ -1000,6 +1000,16 @@ return null; } + /** + * {@inheritDoc} + * + *

This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if the mapping + * function modified this map during computation. + * + * @throws ConcurrentModificationException if it is detected that the + * mapping function modified this map + */ @Override public synchronized V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -1016,7 +1026,9 @@ } } + int mc = modCount; V newValue = mappingFunction.apply(key); + if (mc != modCount) { throw new ConcurrentModificationException(); } if (newValue != null) { addEntry(hash, key, newValue, index); } @@ -1024,6 +1036,16 @@ return newValue; } + /** + * {@inheritDoc} + * + *

This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if the remapping + * function modified this map during computation. + * + * @throws ConcurrentModificationException if it is detected that the + * remapping function modified this map + */ @Override public synchronized V computeIfPresent(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1035,14 +1057,18 @@ Entry e = (Entry)tab[index]; for (Entry prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key.equals(key)) { + int mc = modCount; V newValue = remappingFunction.apply(key, e.value); + if (mc != modCount) { + throw new ConcurrentModificationException(); + } if (newValue == null) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } - modCount++; + modCount = mc + 1; count--; } else { e.value = newValue; @@ -1052,7 +1078,16 @@ } return null; } - + /** + * {@inheritDoc} + * + *

This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if the remapping + * function modified this map during computation. + * + * @throws ConcurrentModificationException if it is detected that the + * remapping function modified this map + */ @Override public synchronized V compute(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1064,14 +1099,18 @@ Entry e = (Entry)tab[index]; for (Entry prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && Objects.equals(e.key, key)) { + int mc = modCount; V newValue = remappingFunction.apply(key, e.value); + if (mc != modCount) { + throw new ConcurrentModificationException(); + } if (newValue == null) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } - modCount++; + modCount = mc + 1; count--; } else { e.value = newValue; @@ -1080,7 +1119,9 @@ } } + int mc = modCount; V newValue = remappingFunction.apply(key, null); + if (mc != modCount) { throw new ConcurrentModificationException(); } if (newValue != null) { addEntry(hash, key, newValue, index); } @@ -1088,6 +1129,16 @@ return newValue; } + /** + * {@inheritDoc} + * + *

This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if the remapping + * function modified this map during computation. + * + * @throws ConcurrentModificationException if it is detected that the + * remapping function modified this map + */ @Override public synchronized V merge(K key, V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1099,14 +1150,18 @@ Entry e = (Entry)tab[index]; for (Entry prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key.equals(key)) { + int mc = modCount; V newValue = remappingFunction.apply(e.value, value); + if (mc != modCount) { + throw new ConcurrentModificationException(); + } if (newValue == null) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } - modCount++; + modCount = mc + 1; count--; } else { e.value = newValue;