Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentHashMap更新存在线程安全值_Java_Multithreading_Java.util.concurrent - Fatal编程技术网

Java ConcurrentHashMap更新存在线程安全值

Java ConcurrentHashMap更新存在线程安全值,java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,我想使用包含一些结果的并发哈希映射 ConcurrentHashMap<Long,AtomicInteger> put操作不安全,如何解决这个问题?put操作是否应该在同步块中?您应该使用ConcurrentHashMap.putIfAbsent(K键,V值)并注意返回值。put()操作本身是以线程安全的方式实现的,即如果您放置相同的键,它将在内部同步 但是,调用不是,即两个线程可以同时添加一个新密钥。您可以尝试putIfAbsent(),如果您得到一个返回值(即非null),您可

我想使用包含一些结果的并发哈希映射

ConcurrentHashMap<Long,AtomicInteger>

put操作不安全,如何解决这个问题?put操作是否应该在同步块中?

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

put()操作本身是以线程安全的方式实现的,即如果您放置相同的键,它将在内部同步

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

if(map.contains(key))
  map.get(key).addAndGet(1);
else
  map.put(key,new AtomicInteger(1));    
//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);
}

或者,如果您使用的是Java8,则可以使用
compute()
方法,根据JavaDoc,该方法是原子执行的。然后,您传递的函数将检查该值是否已经存在。由于整个调用是同步的,您甚至可能不需要使用
AtomicInteger
(取决于您对该值执行的其他操作)。

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

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

这不仅仅是put操作——显示的整个条件块必须在同步块中。或者,您可以使用
putIfAbsent
。使用putIfAbsent似乎更简单。我在同步块中使用了双重检查,而不是在整个条件块中使用。