简体   繁体   English

遍历值时的HashMap线程安全

[英]HashMap threadsafety when iterating over values

Is there any elegant way to make iterating over HashMap.values() threadsafe WITHOUT making a copy of the underlying map? 有没有什么优雅的方法可以使HashMap.values()线程安全地迭代,而无需复制基础地图?

cheers. 干杯。

1) The only possibility with HashMap is to completely synchronize all access to the map. 1)HashMap的唯一可能性是完全同步对地图的所有访问。

2) Use ConcurrentHashMap which is threadsafe (without being fully synchronized internally) 2)使用线程安全的ConcurrentHashMap(无需在内部完全同步)

The Collections class in Java contains methods for making various collections synchronized. Java中的Collections类包含使各种集合同步的方法。 In your case you should use the synchronizedMap() method like this 在您的情况下,您应该像这样使用synchronizedMap()方法

mySyncedMap = Collections.synchronizedMap(myMap);

It is important to note that this method puts a wrapper around the map but the underlying map is still accessible if you keep the reference to it. 重要的是要注意,此方法在地图周围放置了一个包装器,但是如果保留对它的引用,仍可以访问基础地图。

The other option is to use the the ConcurrentHashMap class as it is mentioned in other answers. 另一个选择是使用ConcurrentHashMap类,如其他答案中所述。

I don't really agree with R.Moeller's answer. 我真的不同意R.Moeller的回答。 With a ConcurrentHashMap you don't get ConcurrentModificationExceptions while iterating, but it's still not considered threadsafe (see comments). 使用ConcurrentHashMap您不会在迭代时获得ConcurrentModificationExceptions ,但仍不认为它是线程安全的(请参见注释)。

I would stick with the copy approach, although I wouldn't copy the HashMap. 尽管我不会复制HashMap,但我会坚持使用复制方法。 If you have a HashMap<K,V> myMap iterate over new ArrayList<V>(myMap.values()) . 如果您有HashMap<K,V> myMap遍历new ArrayList<V>(myMap.values()) Makes it easier. 使其更容易。

Another approach would be to use a simple counting loop without iterators. 另一种方法是使用没有迭代器的简单计数循环。

Of course both approaches are not threadsafe so you should include additional checks. 当然,这两种方法都不是线程安全的,因此您应该包括其他检查。 Also, concurrently added elements while going through values() will not be available. 同样,在通过values()时并发添加的元素将不可用。 I don't think that there is an API solution to that... You'd have to extend ConcurrentHashMap , creating an iterator which takes deletions and additions into account. 我认为没有API解决方案...您必须扩展ConcurrentHashMap ,创建一个考虑删除和添加的迭代器。 But I might be wrong with this part and maybe it's even impossible to do. 但是我可能在这部分上做错了,甚至可能做不到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM