これにより、二重チェックのロックが追加され、トランザクションのセマンティクスは同じままです。だからそれは間違っていません。
それが実際に最適化であるかどうかは、使用法によって異なります。私たちは常に、より安価な解決策が存在することがわかっている特別なケースをチェックしたくなります
if A
cheapSolutionForA();
else
genericSolution();
これはうまくいくかもしれませんし、うまくいかないかもしれません-A
まれtrue
に、追加のチェックはそれが節約するよりも多くの費用がかかります。(そして、Aが実際に真である場合、CPU分岐予測を混乱させる可能性があり、A = trueの場合でも、常に汎用ソリューションを使用する方が安価であった可能性があります)
ジョシュアの例でA
は、確かに頻繁に真実です。彼は何度も同じ文字列(同じ値で、IDではない)のインターン文字列を要求している必要があります。したがって、ほとんどの呼び出しで、マップにはすでにキーがあります。
のすべての呼び出しintern()
が異なる文字列を取得する場合、マップにキーが含まれることはなく、彼の最適化は裏目に出ます。「最適化」にはより多くの時間がかかり、何も節約されません。
もちろん、ストリングインターンに関しては、最初のケースの方が実際にはより現実的です。
ただし、一般的に、putIfAbsent()
それがどのように使用されているかを予測することはできないため、この特殊なケースの「最適化」をその中に含めることは賢明ではありません。多くのユースケースでは、競合は少なく、呼び出されたときにマップにキーがない可能性がありますputIfAbsent
。これらの場合、「最適化」が組み込まれていると間違っています。