这是指对提出的问题in this thread的可接受的解决方案

public void insertOrReplace(String key, String value) {
    for (;;) {
        String oldValue = concurrentMap.putIfAbsent(key, value);
        if (oldValue == null)
            return;

        final String newValue = recalculateNewValue(oldValue, value);
        if (concurrentMap.replace(key, oldValue, newValue))
            return;
    }
}

我很想彻底了解代码。

我相信putIfAbsentreplace可以完全视为一个复合操作。这种复合操作是否为原子操作,而无需在对象oldValue上进行显式同步?还是仅仅因为for循环,它保证了原子性?循环到底是做什么的?是否会导致无限循环,使方法永无休止?

最佳答案

首先,原始问题引入了一些奇怪的代码。不确定它的好处是什么,但让我们撇开它。

第二件事,选择的答案和您在此处复制粘贴的答案只是执行与问题中相同代码的另一种方式。

因此,此(bizarre)方法有什么作用:

  • 检查该键是否映射到一个值,如果没有分配该值并且存在。
  • 如果是,请重新计算该值并替换旧值。

  • 那为什么我们需要循环呢?如果2个线程正在重新计算该值并执行“together”替换,则将导致仅1个将成功,并因此从该方法返回。 “松散”线程将需要再次通过该过程。可能会在putIfAbsent调用中获得一个新值,并将重新计算要替换的新值,这一次可能还可以。

    注意事项:
  • 我建议您仔细阅读ConcurrentMapputIfAbsentreplace方法的API。
  • 在极端情况下(实际上永远不会发生),对该方法的调用将永远被卡住,因为它总是“松散”到另一个调用。
  • 我怀疑同步整个方法会更好地避免整个麻烦的循环。但是由于我不完全了解此代码旨在解决的问题,因此无法正式声明这一点。
  • 10-08 02:24