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