ConcurrentHashMap和Fibonacci数字 - 结果不一致

Jok*_*ker 15 java fibonacci concurrenthashmap

我写了一个递归计算斐波纳契数的程序,用a ConcurrentHashMapcomputeIfAbsent()方法:

程序工作绝对正常,当我使用小值8,9,10,但当从程序的值增加永远停止时卡在无限循环中10 to 20

 public class Test {
    static Map<Integer, Integer> concurrentMap = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        System.out.println("Fibonacci result for 20 is" + fibonacci(20));
    }

    static int fibonacci(int i) {
        if (i == 0)
            return i;

        if (i == 1)
            return 1;

        return concurrentMap.computeIfAbsent(i, (key) -> {
            System.out.println("Value is " + key);
            return fibonacci(i - 2) + fibonacci(i - 1);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我为什么它会永远被卡住吗?

Joe*_*e C 27

你正陷入僵局.

computeIfAbsent在ConcurrentHashMap上将锁定相应密钥将进入的存储桶.如果您尝试计算的Fibonacci高于映射中的桶数,则递归调用将尝试锁定已在锁定堆栈中进一步锁定的存储桶.但是,当然,在所有递归调用完成之前,不能释放该锁.因此,你的僵局.

我会重新考虑你在ConcurrentHashMap这里使用的决定.

  • 讽刺的是:HashMap是可重入的,但ConcurrentHashMap不是! (5认同)
  • 可能值得链接到[来自ConcurrentHashMap.computeIfAbsent的JavaDocs](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#computeIfAbsent-K-java.util .function.Function-):"在计算正在进行时,其他线程可能会阻止此地图上的某些尝试更新操作,因此计算应该简短,并且不得尝试更新此映射的任何其他映射." (4认同)