我具有由多线程共享的访问的对象的ConcurrentHashMap访问的的ConcurrentHashMap:安全迭代由多个线程
Map<String, MyConnection> myMap = new ConcurrentHashMap<String, MyConnection>();
类MyConnection的包含对数据源的一些连接。
在稍后阶段,我需要迭代ConcurrentHashMap,调用MyConnection.close()方法并将其从Map中删除。是这样的:
for(String key : myMap.ketSet()) {
MyConnection connection = myMap.get(key);
connection.close();
myMap.remove(key);
}
然而,MYMAP由多个线程,其可被添加,在同一时间从所述的ConcurrentHashMap除去共享。
如何确保上面的for循环可以线程安全地运行?没有要求循环必须删除地图中的所有条目。循环只需要在调用myMap.keySet()时删除所有元素。任何后续添加到地图的元素都不必删除。
很明显,我可以锁定整个for循环,并防止其他线程触摸地图,但我认为这不是性能高效。
有人可以分享你的意见吗?
EDIT1:这个怎么样?这个线程安全吗?
for(MyConnection connection : myMap.values()) {
connection.close();
myMap.remove(connection.getId());
}
每个连接对象都有一个ID,它也是该条目的关键。
这很可能是以下内容的重复。总之,你可以使用迭代器,你需要调用这个迭代器(不是地图)上的remove方法:http://stackoverflow.com/questions/3768554/is-iterating-concurrenthashmap-values-thread-safe – eckes 2014-09-28 19:52:04
@eckes我不同意。这个问题的接受答案声称迭代ConcurrentHashMap通常是安全的,对于给定的“通常”值是正确的。但凯文的用法是不安全的,所以他是正确的问一个单独的问题。 – MikeFHay 2014-09-28 20:01:05
感谢您的回复。我当然会从提到的另一个问题@eckes中获得一些提示。我的要求很简单。我需要的只是安全地移除物体并使地图保持有效状态。如果另一个线程在另一个线程循环时添加了新条目,则可以将新添加的条目留在地图中。如果是这样,上面的循环是安全的吗?或者我必须使用另一个问题中提到的迭代器? – Kevin 2014-09-28 20:12:25