首页 > 解决方案 > ConcurrentSkipListMap.compute() 对于相对更新是否安全?

问题描述

ConcurrentSkipListMap.compute(K, BiFunction)的 Javadoc指出:

尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为 null)。该函数不能保证以原子方式应用一次。

我知道该函数可能会被多次调用,但是“一次原子”指的是什么?

X = X + 1具体来说,在不多次增加映射值的情况下调用函数是否安全?

标签: javajava.util.concurrentconcurrentskiplistmap

解决方案


它是说:

  • 该函数可以被多次调用,并且
  • 这些电话可能会在时间上重叠;即如果多个线程同时调用compute

换句话说,不要期望函数引用被调用的方式是原子行为compute


具体来说,函数调用 X = X + 1 且地图值不会多次递增是否安全?

这取决于“调用 X = X + 1”的含义。(你没有包括一个明确的例子......)

  • 如果这x = x + 1意味着您只是想增加地图的价值,那么:

    • 由于 in中的定义,一次调用compute只会导致一次“增量” 。computeConcurrentMap

    • 但是,当您从compute该值返回时,可能已经增加了不止一次,因为另一个线程同时在做同样的事情。

  • 如果x = x + 1引用了方法引用的副作用,那么所有的赌注都没有了:

    • 它可能已经发生过多次。
    • 如果您的方法引用未正确同步,等等,可能会产生各种令人讨厌的影响。该规范暗示该compute调用不会在外部同步或调用互斥锁或类似的方法引用。正常的并发/内存规则适用......

推荐阅读