有没有什么优雅的方法可以在不复制底层映射的情况下迭代 HashMap.values() 线程安全?
干杯。
1) HashMap 的唯一可能性是完全同步对地图的所有访问。
2)使用线程安全的ConcurrentHashMap(内部没有完全同步)
Java 中的Collections
类包含使各种集合同步的方法。在您的情况下,您应该使用这样的synchronizedMap()
方法
mySyncedMap = Collections.synchronizedMap(myMap);
需要注意的是,此方法在地图周围放置了一个包装器,但如果您保留对底层地图的引用,则仍然可以访问底层地图。
另一种选择是使用ConcurrentHashMap
其他答案中提到的类。
我不太同意 R.Moeller 的回答。使用 aConcurrentHashMap
你在迭代时不会得到ConcurrentModificationExceptions
,但它仍然不被认为是线程安全的(见评论)。
我会坚持使用复制方法,尽管我不会复制 HashMap。如果你有一个HashMap<K,V> myMap
迭代new ArrayList<V>(myMap.values())
. 使它更容易。
另一种方法是使用没有迭代器的简单计数循环。
当然,这两种方法都不是线程安全的,因此您应该包括额外的检查。此外,通过时同时添加的元素values()
将不可用。我认为没有 API 解决方案……您必须扩展ConcurrentHashMap
,创建一个迭代器,将删除和添加考虑在内。但我可能对这部分有误,甚至不可能做到。