在ConcurrentHashMap.computeIfAbsent和ConcurrentHashMap.computeIfPresent中执行`mappingFunction`

tso*_*akp 5 java multithreading java-8

我想看到的描述多少次的行为实际Java文档mappingFunction传递到时可以调用 ConcurrentHashMap.computeIfAbsentConcurrentHashMap.computeIfPresent方法.

Javadoc ConcurrentHashMap.computeIfAbsent似乎很清楚地表示mappingFunction将最多执行一次:

Javadoc for ConcurrentHashMap.computeIfAbsent

如果指定的键尚未与值关联,则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为null.整个方法调用是以原子方式执行的,因此每个键最多应用一次该函数.其他线程在此映射上的某些尝试更新操作可能在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射.

但Javadoc for ConcurrentHashMap.computeIfPresent没有说明mappingFunction可以执行多少次:

Javadoc for ConcurrentHashMap.computeIfPresent

如果存在指定键的值,则尝试在给定键及其当前映射值的情况下计算新映射.整个方法调用以原子方式执行.其他线程在此映射上的某些尝试更新操作可能在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射.

通过查看源代码,它们看起来mappingFunction最多只能执行一次.但我真的希望看到保证这种行为的实际文档.

有这样的文件吗?

Jac*_* G. 3

在 的文档中ConcurrentMap#computeIfPresent,我们看到以下内容:

默认实现相当于对此映射执行以下步骤:

for (V oldValue; (oldValue = map.get(key)) != null; ) {
    V newValue = remappingFunction.apply(key, oldValue);
    if ((newValue == null)
        ? map.remove(key, oldValue)
        : map.replace(key, oldValue, newValue))
     return newValue;
 }
 return null;
Run Code Online (Sandbox Code Playgroud)

尽管文档没有明确说明重新映射函数只会执行一次,但文档提供的等效代码清楚地表明了这一点。

注意:请记住:

当多个线程尝试更新时,映射操作和重新映射函数可能会被多次调用

(强调我的)

  • 谢谢。但是该代码只是用于记录实现如何使用“remappingFunction”,并且不是线程安全的,实际上与“ConcurrentHashMap”中使用的代码完全不同,并且没有给出关于“remappingFunction”可能被调用多少次的明确答案实际的多线程实现。 (2认同)
  • 我不确定您是否看到了最新的编辑,但文档指出“当多个线程尝试更新时,映射操作和 **重新映射函数可能会被多次调用**。” (2认同)
  • 这是来自文档!阅读我的答案中的链接。 (2认同)