Size of ConcurrentHashMap changes behaviour for nested computeIfAbsent calls

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      The size of a ConcurrentHashMap can affect the behaviour of nested computeIfAbsent calls. If the initial size of the map is in the sequence 12, 24, 48, 96, 192, then a nested computeIfAbsent call results in an IllegalStateException thrown (or infinite loop in Java 11). If the initial size is anything else, then the code will succeed.

      Admittedly, the use of nested computeIfAbsent calls is likely to be considered poor practice. However, this inconsistency can lead to bugs being missed.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the code excerpt below (see test case code section)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The result should be consistent, either it should always throw an exception or always succeed (irrespective of the initial map size).
      ACTUAL -
      On Java 11: Code runs in an infinite loop

      Tested on Java 21 and 25:
      Exception in thread "main" java.lang.IllegalStateException: Recursive update
      at java.base/java.util.concurrent.ConcurrentHashMap.transfer(ConcurrentHashMap.java:2568)
      at java.base/java.util.concurrent.ConcurrentHashMap.addCount(ConcurrentHashMap.java:2370)
      at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1792)
      at Scratch.lambda$main$2(scratch_4.java:15)
      at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1724)
      at Scratch.main(scratch_4.java:13)

      ---------- BEGIN SOURCE ----------
      final int size = 12; // or 24, 48, 96, 192...
      final Map<Integer, Integer> map = new ConcurrentHashMap<>();
      IntStream.range(1, size).forEach(i -> map.put(i, i));

      map.computeIfAbsent(size, k ->
      {
          map.computeIfAbsent(size + 1, k2 -> size + 1);
          return size;
      });
      ---------- END SOURCE ----------

        1. Test.java
          0.5 kB
          Patricia Tavares

            Assignee:
            Viktor Klang
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: