提问者:小点点

如何实现并发的清除和复制映射的并发HashMap


在我的项目中,我构建了泽西网络服务。该服务具有每分钟运行一次的计划任务并填充(通过putIfAbsend函数)并发哈希映射(但在之前清除它)。此外,Web服务具有返回映射的json的endpoint:

return gson.toJson(map, type)

通过JAVAAPI函数Clear不是并发函数,gson. toJson只使用MapAPI函数,所以我需要并发的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;
  }
}

这是正确的方法吗?我不想使用读/写锁或同步函数,因为从endpoint性能中获取json对我的Web服务非常重要。

部分填充的map不会打扰我。读/写/更新期间获取性能和不获取异常对我来说是最重要的


共1个答案

匿名用户

ConCurrentHashMap中的Map. lear()的实现是线程安全的,留档中的注释是指从不同线程查看数据时的一致性:

对于putAlllear等聚合操作,并发检索可能仅反映某些条目的插入或删除。

您的解决方案也遇到了同样的问题,并且该方法无法正常工作,因为ConCurrentHashMap中没有全局锁(实际上,读取永远不会锁定)。

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