首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ConcurrentHashMap.putIfAbsent的性能

ConcurrentHashMap.putIfAbsent的性能
EN

Stack Overflow用户
提问于 2011-04-16 11:15:28
回答 2查看 2.4K关注 0票数 5

在54:15的his talk about Effective Java中,Joshua Bloch建议在使用putIfAbsent之前使用get,以提高性能和并发性。这就引出了一个问题,为什么这个优化没有像这样内置

代码语言:javascript
运行
复制
public V BETTER_putIfAbsent(K key, V value) {
    V result = get(key);
    if (result!=null) return result;
    return ORIGINAL_putIfAbsent(key, value);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-16 13:07:20

这添加了双重检查锁定,事务语义保持不变;因此它是正确的。

它是否真的是优化取决于使用情况。我们总是想检查那些我们知道有更便宜的解决方案的特殊情况。

代码语言:javascript
运行
复制
if A
    cheapSolutionForA();
else
    genericSolution();

这可能会起作用,也可能不起作用-如果A很少是true,那么额外的检查成本就会超过节省的成本。(当A确实有时为真时,它可能会扰乱CPU分支预测,即使当A=true时,总是使用通用解决方案可能会更便宜)

在Joshua的例子中,A确实经常是真的。他必须多次请求同一个字符串的实习生字符串(在值上相同,而不是在标识上),因此在大多数调用中,map已经具有键。

如果每次对intern()的调用都得到一个不同的字符串,那么映射就永远不会有键,他的优化就会适得其反--“优化”会花费更多的时间,而且不会节省任何时间。

当然,当涉及到字符串实习生时,第一种情况在实践中更现实。

一般来说,putIfAbsent()不能预测它是如何被使用的,所以在它里面包含这种特殊情况的“优化”是不明智的。在许多用例中,争用是低的,当调用putIfAbsent时,映射很可能没有键,在这些情况下,如果“优化”是内置的,这将是错误的。

票数 1
EN

Stack Overflow用户

发布于 2011-04-16 12:59:49

我猜这是因为性能取决于使用模式。对于大多数putIfAbsent调用都会成功的map,使用get保护它会更慢。对于putIfAbsent经常失败的映射,使用get保护它会更快。

通过不对常见故障情况进行优化,您可以自由选择哪个方法更快。

在视频中的示例中,putIfAbsent通常会失败,因此使用get来保护它会更快。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5684252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档