Java ConcurrentHashMap中的实时锁定

Java ConcurrentHashMap中的实时锁定,java,concurrency,java.util.concurrent,concurrenthashmap,livelock,Java,Concurrency,Java.util.concurrent,Concurrenthashmap,Livelock,当用于计算的函数在同一映射上调用#ComputeFabSent时,我在并发hashmap#ComputeFabSent中遇到了live lock条件 从概念上讲,调用如下所示 final Map<String, Boolean> map = new ConcurrentHashMap<>(); map.computeIfAbsent("k1", k1 -> map.computeIfAbsent("k2", k2 -> Boolean.TRUE)); fin

当用于计算的函数在同一映射上调用#ComputeFabSent时,我在并发hashmap#ComputeFabSent中遇到了live lock条件

从概念上讲,调用如下所示

final Map<String, Boolean> map = new ConcurrentHashMap<>();
map.computeIfAbsent("k1", k1 -> map.computeIfAbsent("k2", k2 -> Boolean.TRUE));
final Map=new ConcurrentHashMap();
map.computeFabSent(“k1”,k1->map.computeFabSent(“k2”,k2->Boolean.TRUE));
(在两次计算之间,cpu消耗约3毫秒)。不幸的是,我不能提出好的单元测试来一致地重现问题

但是

如果计算函数试图移除调用它的密钥,则另一个活动锁可能会提供一些线索:

 final Map<String, Boolean> map = new ConcurrentHashMap<>();
 map.computeIfAbsent("k", k -> map.remove("k"));
final Map=new ConcurrentHashMap();
map.computeFabSent(“k”,k->map.remove(“k”);
虽然第二个示例使用并发哈希映射相当复杂,但它会产生与第一个活动锁相同的stacktrace,因此可能会有所帮助

任何帮助都将不胜感激

文档中明确指出:

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

我的。内部
computeIfAbsent
同步包含密钥的哈希表条目。当您修改另一个密钥时,可能会出现意外锁定,而该密钥恰好落入当前正在处理的同一条目中


一般来说,您应该避免此类修改。不幸的是,您没有为您的问题提供足够的上下文,因此我无法提出替代解决方案。

Doh,我读了两遍javadoc,错过了函数契约。谢谢你的强调!在Doug的存储库中,但尚未在JDK版本中。