Since Java 9 HashMap.computeIfAbsent() throws ConcurrentModificationException on attempt to memoize recursive function results
ConcurrentModificationException
is thrown because slowFib
is modifying multiple keys and values. If you look at Java 9 HashMap.computeIfAbsent()
code you will find that the exception is thrown here:
int mc = modCount;
V v = mappingFunction.apply(key);
if (mc != modCount) { throw new ConcurrentModificationException(); }
Each invocation of slowFib
attempts to modify values mapped to keys n-1
and n-2
.
The modCount
check is not performed in Java 8 HashMap.computeIfAbsent()
code. This is a bug in Java 8, your approach doesn't work in all cases as per JDK-8071667 HashMap.computeIfAbsent() adds entry that HashMap.get() does not find which added the modCount
check in Java 9:
If the function supplied to computeIfAbsent adds items to the same HashTable on which the function is called from and the internal table is enlarged because of this, the new entry will be added to the wrong place in the Map's internal table making it inaccessible.