繁体   English   中英

ConcurrentHashMap更新存在值线程安全

[英]ConcurrentHashMap update exists value thread safe

我想使用并发哈希映射来保存一些结果,

ConcurrentHashMap<Long,AtomicInteger>

如果key不存在则添加新条目,或者按键和增量获取值,如下所示:

if(map.contains(key))
  map.get(key).addAndGet(1);
else
  map.put(key,new AtomicInteger(1));    

put操作不安全,如何解决这个问题? 放操作应该在synchronized块内吗?

put()操作本身是以线程安全的方式实现的,即如果你输入相同的密钥,它将在内部同步。

但是,调用不是,即两个线程可以同时添加新密钥。 你可以尝试putIfAbsent() ,如果你得到一个返回值(即非null),你可以调用get方法。 因此,您可以像这样更改您的代码:

//this only adds a new key-value pair if there's not already one for the key
if( map.putIfAbsent(key,new AtomicInteger(1)) != null ) {    
  map.get(key).addAndGet(1);
}

或者,如果您使用的是Java 8,则可以使用compute()方法,该方法根据JavaDoc以原子方式执行。 您传递的函数将检查该值是否已存在。 由于整个调用是同步的,你可能甚至不需要使用AtomicInteger (取决于你对该值做了什么)。

您应该使用ConcurrentHashMap.putIfAbsent(K key, V value)并注意返回值。

在Java 8中,您可以使用ConcurrentHashMap的computeIfAbsent来提供初始值:

map.computeIfAbsent(key, new AtomicInteger(0)).addAndGet(1)

暂无
暂无

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

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