散列图并发问题
我有一个Hashmap,出于速度的原因,我想不要求锁定。 假设我不介意陈旧的数据,是否会更新它并同时访问它会导致任何问题?
我的访问是获取,而不是遍历它,删除是更新的一部分。
是的,这会造成重大问题。 一个例子是当向哈希映射添加一个值时会发生什么:这可能导致表的重新哈希,并且如果在另一个线程迭代碰撞列表(哈希表“桶”)时发生这种情况,该线程可能会错误地无法找到地图中存在的密钥。 HashMap
对于并发使用显然是不安全的。
改用ConcurrentHashMap
。
同步或使用ConcurrentHashMap的重要性不能低估。
直到几年前,我才被误导了,因为我只能同步HashMap上的put和remove操作。 这当然是非常危险的,实际上会导致HashMap.get()中的某些(我认为早期1.5)jdk的无限循环。
几年前我做了什么(而且真的不应该这样做):
public MyCache {
private Map<String,Object> map = new HashMap<String,Object>();
public synchronzied put(String key, Object value){
map.put(key,value);
}
public Object get(String key){
// can cause in an infinite loop in some JDKs!!
return map.get(key);
}
}
编辑 :以为我会添加一个不能做的例子(见上文)
如有疑问,请查看课程的Javadocs:
请注意,此实现不同步。 如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,则它必须在外部同步。 (结构修改是指添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键相关联的值不是结构修改。)这通常通过同步某个自然封装映射的对象来实现。 如果不存在这样的对象,则应使用Collections.synchronizedMap方法“映射”该映射。 这最好在创建时完成,以防止意外的不同步访问地图:
Map m = Collections.synchronizedMap(new HashMap(...));
(重点不是我的)
因此,根据你说你的线程将从Map中删除映射的事实,答案是肯定会导致问题,而且肯定是不安全的 。
链接地址: http://www.djcxy.com/p/91973.html