【问题标题】:Live Lock in ConcurrentHashMapConcurrentHashMap 中的活锁
【发布时间】:2015-12-17 04:15:37
【问题描述】:

当用于计算的函数在同一个映射上调用 #computeIfAbsent 时,我在并发哈希映射 #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"));

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

任何帮助将不胜感激!

【问题讨论】:

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


【解决方案1】:

ConcurrentHashMap.computeIfAbsent 文档明确表示:

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

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

一般而言,您应该避免此类修改。不幸的是,您没有为您的问题提供足够的背景信息,因此我无法提出替代解决方案。

【讨论】:

  • Doh,我读了两次 javadoc,错过了函数合同。感谢您的强调!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 2013-05-06
相关资源
最近更新 更多