在his talk about Effective Java at 54:15,Joshua Bloch建议在putIfAbsent之前使用get以提高性能和并发性.这引出了一个问题,为什么这个优化已经没有像
public V BETTER_putIfAbsent(K key,V value) {
V result = get(key);
if (result!=null) return result;
return ORIGINAL_putIfAbsent(key,value);
}
最佳答案
这增加了双重检查锁定,事务语义保持不变;所以没有错.
原文链接:https://www.f2er.com/java/437825.html它是否实际上是一种优化取决于使用情况.我们总是试图检查我们知道存在更便宜的解决方案的特殊情况
if A
cheapSolutionForA();
else
genericSolution();
这可能有用,或者没有 – 如果A很少是真的,额外的检查费用比它节省的多. (当A确实有时真的,它可以破坏cpu分支预测,即使A = true,总是使用通用解决方案可能更便宜)
在约书亚的例子中,A确实经常是真的.他必须多次请求相同字符串的实习字符串(值相同,而不是同一性),因此在大多数调用中,地图已经有了密钥.
如果对intern()的每次调用都得到一个不同的字符串,那么地图永远不会有密钥,并且他的优化会发生逆火 – “优化”会花费更多时间,并且不会保存.
当然,在字符串实习生方面,第一种情况在实践中更为现实.
一般来说,putIfAbsent()无法预测它的使用方式,因此在其中包含这种特殊情况“优化”是不明智的.在许多用例中,争用率很低,当调用putIfAbsent时,映射很可能没有密钥,如果内置“优化”,则在这些情况下会出错.