ConcurrentHashMap中的Live Lock

时间:2015-09-20 11:10:01

标签: java concurrency java.util.concurrent concurrenthashmap livelock

当用于计算的函数在同一个地图上调用#computeIfAbsent时,我在并发hashmap #computeIfAbsent中遇到了实时锁定条件。

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

final Map<String, Boolean> map = new ConcurrentHashMap<>();
map.computeIfAbsent("k1", k1 -> map.computeIfAbsent("k2", k2 -> Boolean.TRUE));

(在计算之间烧掉大约3ms的cpu)。不幸的是,我不能提出良好的单元测试来一致地重现问题。

然而

如果计算函数试图删除调用它的键,则还有另一个活锁可能会给出一些线索:

 final Map<String, Boolean> map = new ConcurrentHashMap<>();
 map.computeIfAbsent("k", k -> map.remove("k"));

虽然第二个例子是使用并发哈希映射的相当复杂的,但它导致与第一个实时锁相同的堆栈跟踪,因此可能会有所帮助。

任何帮助都将受到高度赞赏!

1 个答案:

答案 0 :(得分:4)

ConcurrentHashMap.computeIfAbsent文档明确说明:

  

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

强调我的。内部computeIfAbsent在包含密钥的哈希表条目上进行同步。当您修改恰好与当前正在处理的条目相同的另一个密钥时,您可能会遇到意外锁定。

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