ConcurrentHashMap的迭代

时间:2013-06-04 14:35:17

标签: java concurrenthashmap

我正在阅读ConcurrentHashMap

我读到它提供了一个不需要同步的迭代器,甚至允许在迭代期间修改Map,因此不会有ConcurrentModificationException

我想知道这是否是一件好事,因为我可能无法获得该元素,在迭代期间放入ConcurrentHashMap,因为另一个线程可能已经改变了它。

我的想法是否正确?如果是,是好还是坏?

3 个答案:

答案 0 :(得分:4)

  

我想知道这是否是一件好事,因为我可能没有得到该元素,在迭代期间放入ConcurrentHashMap,因为另一个线程可能已经改变了它。

我不认为这应该是一个问题 - 如果您使用同步并且执行迭代的线程碰巧抓住锁并在插入值的线程之前执行它的循环,则同样的声明也是如此。

如果您需要在线程之间进行某种协调以确保在其他操作之后(以及之后)执行某些操作,那么无论使用何种Map,您仍需要管理此协调。

答案 1 :(得分:1)

通常,ConcurrentHashMap弱一致的迭代器就足够了。如果你想要一个强一致的迭代器,那么你有几个选择:

  1. ctrie是一个哈希数组映射trie,提供恒定时间快照。数据结构有Java source code
  2. Clojure有一个PersistentHashMap你可以使用 - 这可以让你迭代数据的快照。
  3. 使用本地数据库,例如HSQLDB来存储数据而不是使用ConcurrentHashMap。使用key | timestamp的复合主键,当“更新”值时,您将使用当前时间戳存储新条目。要获取迭代器,请使用where timetamp < System.currentTimeMillis()子句检索结果集,然后迭代结果集。
  4. 在任何一种情况下,你都在迭代快照,所以你有一个强大的一致迭代器;在前一种情况下,您可能会遇到内存不足的风险,而后一种情况则是一种更复杂的解决方案。

答案 2 :(得分:0)

并发的重点 - 你要承认并发活动,并且不相信所有访问都是序列化的。对于大多数集合,如果不为它工作,就不能指望元素间的一致性。

如果您不关心查看最新数据,但想要一致(但可能是旧的)数据视图,请查看纯Finger Trees等功能结构。

相关问题