Java 如何为ConcurrentHashMap实现并发清除和复制映射
在我的项目中,我构建了Jersey Web服务。此服务具有每分钟运行一次的计划任务,并(通过putIfAbsent函数)填充并发哈希映射(但之前会将其清除)。此外,web服务具有返回映射的json的端点: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
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字段作为不可变映射交换呢?这样你就不会看到一张局部填充的地图了