Java 如何为ConcurrentHashMap实现并发清除和复制映射

Java 如何为ConcurrentHashMap实现并发清除和复制映射,java,concurrency,gson,concurrenthashmap,Java,Concurrency,Gson,Concurrenthashmap,在我的项目中,我构建了Jersey Web服务。此服务具有每分钟运行一次的计划任务,并(通过putIfAbsent函数)填充并发哈希映射(但之前会将其清除)。此外,web服务具有返回映射的json的端点: return gson.toJson(map, type) 通过JAVA API函数clear不是一个并发函数,而gson.toJson只使用Map API函数,所以我需要并发clear和getMap/copyMap函数。所以我想自己用并发函数的用法来实现这些函数: public class

在我的项目中,我构建了Jersey Web服务。此服务具有每分钟运行一次的计划任务,并(通过putIfAbsent函数)填充并发哈希映射(但之前会将其清除)。此外,web服务具有返回映射的json的端点:

return gson.toJson(map, type)
通过JAVA API函数clear不是一个并发函数,而gson.toJson只使用Map API函数,所以我需要并发clear和getMap/copyMap函数。所以我想自己用并发函数的用法来实现这些函数:

public class ExtendedConcurrentHashMap<K,V> extends ConcurrentHashMap<K,V> {
  private final ConcurrentHashMap<K,V> map;

  public ExtendedConcurrentHashMap(ConcurrentHashMap<K,V> map) {
    this.map = map;
  }

  public void clear() {
    ConcurrentHashMap.KeySetView<K,V> keySet = map.keySet(); //concurrent function
    Iterator<K> iterator = keySet.iterator();

    while(iterator.hasNext()) {
      K keyToRemove = iterator.next();
      map.compute(keyToRemove, (key,value) -> null); // concurrent function
    }
  }

  public Map<K,V> getMap() {
    Map<K,V> mapCopy = new HashMap<>();
    map.forEach((key,value) -> mapCopy.put(key,value)); // concurrent function

    return mapCopy;
  }
}
公共类ExtendedConcurrentHashMap扩展ConcurrentHashMap{
私有最终ConcurrentHashMap映射;
公共扩展ConcurrentHashMap(ConcurrentHashMap映射){
this.map=map;
}
公共空间清除(){
ConcurrentHashMap.KeySetView keySet=map.keySet();//并发函数
迭代器迭代器=keySet.Iterator();
while(iterator.hasNext()){
K keyToRemove=iterator.next();
compute(keyToRemove,(key,value)->null);//并发函数
}
}
公共地图getMap(){
Map mapCopy=新建HashMap();
map.forEach((键,值)->mapCopy.put(键,值));//并发函数
返回地图副本;
}
}
这样做对吗?我不想使用读/写锁或同步函数,因为从端点获取json对我的web服务非常重要


部分填充的地图不会打扰我。在读/写/更新过程中获得性能和不出现异常对我来说是最重要的

ConcurrentHashMap
中实现
Map.clear()
是线程安全的。文档中的注释涉及从不同线程查看时数据的一致性:

对于聚合操作,如
putAll
clear
,并发检索可能只反映插入或删除某些条目

您的解决方案也遇到了同样的问题,并且由于
ConcurrentHashMap
中没有全局锁(实际上,reads never lock)


如果您希望以原子方式执行批量操作,则必须手动执行锁定
Collections.synchronizedMap()
提供了一个简单的包装器。包装器本身被用作所有操作的锁,因此在包装器上同步可以执行多个操作,而不用担心其他线程会在工作完成之前执行更新或读取。

clear()如果您使用ConcurrentHashMap,那么它是线程安全的。只需使用
Collections.synchronizedMap
来包装普通的
HashMap
。这将使您获得一致的数据视图。@teppic和kill在多线程环境中的性能:)@Cargeh:我保证op不会注意到差异。为什么不使用volatile字段作为不可变映射交换呢?这样你就不会看到一张局部填充的地图了