【发布时间】:2013-04-19 03:13:37
【问题描述】:
我有以下情况:
- 一种只能扩展的数据结构(我只 在尾部添加东西)
- 我需要能够跟踪我已经拥有的元素 见过(我有一个索引,理想情况下我希望能够开始 从这个特定元素再次遍历列表)
- 我希望读取永远不会阻塞,并添加 新元素只锁定队列的尾部而不是 整个队列
这是一个被多个线程大量修改的结构。
最好的数据结构是什么?
数组列表。如果能够直接访问使用索引看到的最后一个元素,这将是理想的,但它会导致并发修改异常。我可以使其同步,但希望避免锁定(或除最后一个元素之外的任何锁定,因为它是唯一可能存在并发写入以添加新元素的锁定)
并发链接队列。这将解决我的并发问题,但问题是我必须存储迭代的当前位置而不是整数索引。这有一个问题,它返回一个弱一致的迭代器,它不能保证返回自迭代器创建以来已添加到列表中的新对象(来源:javadoc)
ConcurrentHashMap 以索引为键。这样做的好处是我可以直接访问与正确索引相对应的数据,但问题是没有“getNext”运算符可以让我有效地遍历从索引到索引 + 1 等的元素
向量这将解决我的大部分问题,即允许不会引发并发修改异常并允许直接访问的东西。但是,鉴于所有方法都是同步的,与数组列表相比,性能较差。鉴于我只想扩展结构,而不是在中间插入记录,我不愿意采用这种重量级的解决方案,其中读取也会受到性能影响(鉴于我的用例,元素的索引从来没有真正改变过,所以不需要同步不是尾部的读取)
自定义数据结构:保留我要存储的对象的数组和指向该数组尾部(最后一个元素集)的指针,插入新对象时,锁定尾部并尾巴指向的物体。当对象超过其当前大小时,进行锁定调整大小操作。
最佳策略/其他更有效的实施方式是什么?
【问题讨论】:
-
您可以使用 java.util.Vector 代替 ArrayList。这将解决您的同步问题。
-
+1 为您的研究工作。
-
@user1018513 “我需要能够跟踪我已经看到的元素”是什么意思。你能解释一下吗?
-
请结合“多线程大量修改”来说明“只能扩展”。这是否意味着它会快速而永久地增长?另外——你试图用那个数据结构解决什么问题?这应该是发布-订阅者队列的变体还是其他东西?
-
@user1018513 在遍历时您是希望始终随机访问还是只希望随机访问(即:开始遍历,执行其他操作,从我离开的地方继续遍历)。
标签: java data-structures concurrency