java - 结合 putIfAbsent 并替换为 ConcurrentMap

标签 java concurrency synchronization concurrenthashmap

我有一个用例,我必须这样做

  • 如果键不存在于 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);
    }

你认为它正确且线程安全吗?

有没有更简单的方法?

最佳答案

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

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;
    }
}

关于java - 结合 putIfAbsent 并替换为 ConcurrentMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10279629/

相关文章:

PHP - 将 MySQL 联系人与 Exchange 同步

java - 为什么在运行 maven install 时出现 "package does not exist"错误?

java - 当预期迭代一次时,For 循环对输入迭代三次

c++ - 为什么不在 pop 之后运行任务并返回 true?

c++ - 在调用 future.get() 之前销毁 std::promise 是否可以?

java - JAVA中Synchronized和Final的关系

java - HashSet contains() 为自定义对象返回 false。 hashCode() 和 equals() 似乎实现正确

java - java 中的实例变量是否不允许使用某些访问修饰符?

java - 在java中同步ArrayList的正确方法