我需要一个ArrayList状结构让刚刚以下操作并发的ArrayList
get(int index)
add(E element)
set(int index, E element)
iterator()
因为迭代器在正使用的许多地方,使用Collections#synchronizedList
窝这太容易出错了。该列表可能会增长到几千个元素,并被大量使用,所以我很确定,CopyOnWriteArrayList
会太慢。我会先从它开始避免过早的优化,但我敢打赌它不会很好。
大多数访问将是单线程读取。所以我在问这是什么合适的数据结构。
我尽管这在包裹东西synchronizedList
提供同步迭代器会做,反而会ConcurrentModificationException
它不是因为。考虑到并发行为,我显然需要通过后续的读取和迭代器来看到所有更改。
迭代器不必显示一致的快照,它可能会也可能不会看到通过set(int index, E element)
的更新,因为此操作仅用于替换具有更新版本的项目(包含一些添加的信息,与此无关迭代器的用户)。这些项目是完全不可变的。
我明确说明了为什么CopyOnWriteArrayList
不会这样做。 ConcurrentLinkedQueue
没有问题,因为它缺少索引访问。我只需要几个操作,而不是完全成熟的ArrayList
。所以除非任何java并发列表相关问题是this question的副本,这一个不是。
你可能想尝试Clojure的['PersistentVector'](https://github.com/clojure/clojure/blob/master/src/jvm/ clojure/lang/PersistentVector.java),它也是写时复制,但不是一个天真的单片阵列;而是一个宽而浅的数组树。在我链接到的源代码的末尾,您会发现测试代码。 – 2014-10-17 11:34:21
@skaffman您可以在关闭它之前仔细阅读这个问题吗?查看我的更新。 – maaartinus 2014-10-17 12:32:15
@MarkoTopolnik这会工作,但代码看起来很奇怪。它还增加了我不关心的操作所需的一些开销。顺便说一句,你可以投票重新开放吗?恕我直言,MOD在阅读时有点太快。 – maaartinus 2014-10-17 13:24:46