Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 也许我';我发现了concurrenthashmap的一个bug_Java 8_Concurrenthashmap - Fatal编程技术网

Java 8 也许我';我发现了concurrenthashmap的一个bug

Java 8 也许我';我发现了concurrenthashmap的一个bug,java-8,concurrenthashmap,Java 8,Concurrenthashmap,当我想要有效地实现^b时,我使用并发hashmap来存储计算值,代码是 private static final ConcurrentHashMap<String,Long> cache = new ConcurrentHashMap(); public long pow(long a, long b){ System.out.printf("%d ^ %d%n",a,b); if(b == 1L){ return a; } if(

当我想要有效地实现^b时,我使用并发hashmap来存储计算值,代码是

private static final ConcurrentHashMap<String,Long> cache = new ConcurrentHashMap();

public long pow(long a, long b){
    System.out.printf("%d ^ %d%n",a,b);
    if(b == 1L){
        return a;
    }
    if( b == 2L){
        return a*a;
    }
    long l = b/2;
    long r = b - l;

    return cache.computeIfAbsent(a+","+l,k->pow(a,l)) * cache.computeIfAbsent(a+","+r,k->pow(a,r));
}
但是在输出之后

2 ^ 30
2 ^ 15
2 ^ 7
它被阻塞了,通过使用
jstack-lpid
我得到了下面的信息

"main" #1 prio=5 os_prio=31 tid=0x00007f910e801800 nid=0x1703 runnable [0x0000700000217000]
   java.lang.Thread.State: RUNNABLE
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1718)
    at interview.Pow.pow(Pow.java:28)
    at interview.Pow.lambda$pow$0(Pow.java:28)
    at interview.Pow$$Lambda$1/1807837413.apply(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    - locked <0x000000076b72d930> (a java.util.concurrent.ConcurrentHashMap$ReservationNode)
    at interview.Pow.pow(Pow.java:28)
    at interview.Pow.lambda$pow$0(Pow.java:28)
    at interview.Pow$$Lambda$1/1807837413.apply(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    - locked <0x000000076b72d060> (a java.util.concurrent.ConcurrentHashMap$ReservationNode)
    at interview.Pow.pow(Pow.java:28)
    at interview.Pow.testPow(Pow.java:32)
所以在这种情况下,它不能打破循环

for (Node<K,V>[] tab = table;;) {...}
for(Node[]tab=table;;){…}
无限循环


这是一个bug还是故意设计的?

正如C-Otto已经评论的那样,您在第一个
computeIfAbsent()
方法调用中调用了第二个
computeIfAbsent()
。明确规定:

在计算过程中,其他线程对此映射尝试的某些更新操作可能会被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射。


因此,这在
ConcurrentHashMap
实现中并不是错误,而是在代码中。

在映射上运行
ComputeFabSent
时递归调用
pow
。因此,您有两次尝试写入映射。是的,ConcurrentHashMap只是为并发使用而设计的,而不是递归使用,因此如果知道没有并发操作,应该将其更改为使用普通HashMap。但在一些罕见的场景中,可能同时存在并发操作和递归操作。那么在这种情况下,我应该使用什么地图?Collections.synchronizedMap()?
if (fh >= 0) {...}
for (Node<K,V>[] tab = table;;) {...}