title: Recursive ConcurrentHashMap.computeIfAbsent() call never terminates. Bug or "feature"?
body: <p>Some time ago, <a href="http://blog.jooq.org/2014/02/28/java-8-friday-goodies-easy-as-pie-local-caching">I've blogged about a Java 8 functional way of calculating fibonacci numbers recursively</a>, with a <code>ConcurrentHashMap</code> cache and the new, useful <code>computeIfAbsent()</code> method:</p>
  
  <pre><code>import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  
  public class Test {
      static Map&lt;Integer, Integer&gt; cache = new ConcurrentHashMap&lt;&gt;();
  
      public static void main(String[] args) {
          System.out.println(
              "f(" + 8 + ") = " + fibonacci(8));
      }
  
      static int fibonacci(int i) {
          if (i == 0)
              return i;
  
          if (i == 1)
              return 1;
  
          return cache.computeIfAbsent(i, (key) -&gt; {
              System.out.println(
                  "Slow calculation of " + key);
  
              return fibonacci(i - 2) + fibonacci(i - 1);
          });
      }
  }
  </code></pre>
  
  <p>I chose <code>ConcurrentHashMap</code> because I was thinking of making this example even more sophisticated by introducing parallelism (which I didn't in the end).</p>
  
  <p>Now, let's increase the number from <code>8</code> to <code>25</code> and observe what happens:</p>
  
  <pre><code>        System.out.println(
              "f(" + 25 + ") = " + fibonacci(25));
  </code></pre>
  
  <p>The program never halts. Inside the method, there's a loop that just runs forever:</p>
  
  <pre><code>for (Node&lt;K,V&gt;[] tab = table;;) {
      // ...
  }
  </code></pre>
  
  <p>I'm using:</p>
  
  <pre class="lang-none prettyprint-override"><code>C:\Users\Lukas&gt;java -version
  java version "1.8.0_40-ea"
  Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b23)
  Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
  </code></pre>
  
  <p><a href="http://blog.jooq.org/2014/02/28/java-8-friday-goodies-easy-as-pie-local-caching/#comment-121821">Matthias, a reader of that blog post also confirmed the issue (he actually found it)</a>.</p>
  
  <p>This is weird. I would have expected any of the following two:</p>
  
  <ul>
  <li>It works</li>
  <li>It throws a <code>ConcurrentModificationException</code></li>
  </ul>
  
  <p>But just never halting? That seems dangerous. Is it a bug? Or did I misunderstand some contract?</p>