繁体   English   中英

如何在ConcurrentHashMap线程安全中更新值

[英]How to update a Value in a ConcurrentHashMap threadsafe

我需要更新ConcurrentHashmap中的值,但是不确定如何安全地执行此线程。

Hashmap是ConcurrentHashMap,我需要获取自定义类的实例,对其进行一些操作,然后再将更新后的值放回去。

有什么方法可以将此获取-更改-输入操作结合到原子上吗?

提前致谢

ConcurrentHashMapcomputeIfPresent方法是可能的。 来自javadocs:如果存在指定键的值,则尝试在给定键及其当前映射值的情况下计算新映射。 整个方法调用是原子执行的( 期望计算应该简短 )。

通常,该方法如何工作? 一些示例代码:

考虑具有键和值的Map<String, Integer> map{four=4, one=1, ten=10, two=2, three=3, five=5, eleven=11}

(1)使用新值更新映射(请注意,lambda是一个BiFunction返回新计算出的值):

map.computeIfPresent("ten", (k, v) -> new Integer(100));

(2)该函数返回null,将现有映射删除:

map.computeIfPresent("eleven", (k, v) -> null);

(3)没有添加映射,因为没有现有的映射:

map.computeIfPresent("twenty", (k, v) -> new Integer(20));

编辑:

关于compute()注意事项:使用相同的输入map数据(和方法参数), compute方法的工作原理类似,但是对于情况3。注意情况3,可以添加新的映射:

(3)添加了新的映射。

您可以使用ConcurrentHashMaps computeIfPresent https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#computeIfPresent-K-java.util.function.BiFunction-

但是由于computeIfPresent是一个昂贵的操作,因为它的原子操作,并且在BiFunction计算期间某些更新操作将被其他线程阻止。 您可以通过对并发哈希图的读取操作来阻止此操作,该操作相当快,如果返回的结果不为null,则调用computeIfPrsent

下面的代码获取键“ 1”的值并将其加100,然后以原子方式放回地图

ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
        map.put(1,100);
        Integer value = map.get(1);
        if (value != null)
            map.computeIfPresent(1, (key, oldValue) -> oldValue + 100);
    }

我会说你可以用

map.compute(key,  (k,v) -> {
                      if(k != null) {
                        return v+1;
                      } else {
                        return some_var;
                      }
                    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM