一尘不染

组合putIfAbsent并替换为ConcurrentMap

java

我有一个用例,我必须

  • 如果键在ConcurrentHashMap中不存在,则插入一个新值
  • 如果键已经存在于ConcurrentHashMap中,则新值将旧值替换为新值(其中新值是从旧值派生的(不是昂贵的操作))

我提供以下代码:

public void insertOrReplace(String key, String value) {
        boolean updated = false;
        do {
            String oldValue = concurrentMap.get(key);
            if (oldValue == null) {
                oldValue = concurrentMap.putIfAbsent(key, value);
                if (oldValue == null) {
                    updated = true;
                }
            }
            if (oldValue != null) {
                final String newValue = recalculateNewValue(oldValue, value);
                updated = concurrentMap.replace(key, oldValue, newValue);
            }
        } while (!updated);
    }

您认为它是正确的并且是线程安全的吗?

有没有更简单的方法?


阅读 223

收藏
2020-12-03

共1个答案

一尘不染

您可以使用下面与您的代码等效的代码来使其短一些。我已经对数以千计的线程进行并发访问进行了一些压力测试:它按预期运行,并执行了许多重试(循环)(显然,您无法在并发世界中通过测试来证明其正确性)。

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;
    }
}
2020-12-03