1

有没有什么优雅的方法可以在不复制底层映射的情况下迭代 HashMap.values() 线程安全?

干杯。

4

3 回答 3

3

1) HashMap 的唯一可能性是完全同步对地图的所有访问。

2)使用线程安全的ConcurrentHashMap(内部没有完全同步)

于 2013-09-04T10:07:23.690 回答
2

Java 中的Collections类包含使各种集合同步的方法。在您的情况下,您应该使用这样的synchronizedMap()方法

mySyncedMap = Collections.synchronizedMap(myMap);

需要注意的是,此方法在地图周围放置了一个包装器,但如果您保留对底层地图的引用,则仍然可以访问底层地图。

另一种选择是使用ConcurrentHashMap其他答案中提到的类。

于 2013-09-04T20:06:05.903 回答
1

我不太同意 R.Moeller 的回答。使用 aConcurrentHashMap你在迭代时不会得到ConcurrentModificationExceptions,但它仍然不被认为是线程安全的(见评论)。

我会坚持使用复制方法,尽管我不会复制 HashMap。如果你有一个HashMap<K,V> myMap迭代new ArrayList<V>(myMap.values()). 使它更容易。

另一种方法是使用没有迭代器的简单计数循环。

当然,这两种方法都不是线程安全的,因此您应该包括额外的检查。此外,通过时同时添加的元素values()将不可用。我认为没有 API 解决方案……您必须扩展ConcurrentHashMap,创建一个迭代器,将删除和添加考虑在内。但我可能对这部分有误,甚至不可能做到。

于 2013-09-04T10:28:49.353 回答