什么集合支持多个同时插入?

时间:2010-06-22 12:29:12

标签: java performance multithreading data-structures

我们正在开发一个包含多个工作线程的Java应用程序。这些线程必须向我们的UI线程提供大量计算结果。结果的顺序无关紧要。

现在,所有线程只是将结果推送到同步堆栈 - 但这意味着每个线程必须等待其他线程才能传递结果。

是否存在支持同时插入的数据结构,每个插入在固定时间内完成?

谢谢,

马丁

5 个答案:

答案 0 :(得分:10)

ConcurrentLinkedQueue专为高争用而设计。生产者在一端排队东西,消费者在另一端收集元素,所以一切都将按照添加的顺序进行处理。

ArrayBlockingQueue对于较低的争用更好,空间开销较低。

编辑:虽然这不是您要求的。 Simultaneuos插入?您可能希望为每个线程提供一个输出队列(例如,ArrayBlockingQueue),然后让UI线程轮询单独的队列。但是,我认为您会发现以上两个Queue实现中的一个已足够。

答案 1 :(得分:3)

  

现在,所有线程都只是推送   他们的结果是同步的   堆栈 - 但这意味着每一个   线程必须等待其他线程   在结果公布之前。

您是否有任何证据表明这实际上是一个问题?如果这些线程执行的计算甚至是最小的一点复杂(并且你没有数百万个线程),那么结果堆栈上的锁争用只是一个非问题,因为当任何给定的线程传递其结果时,所有其他人最有可能忙于计算。

答案 2 :(得分:1)

退后一步,评估性能是否是此处的关键设计考虑因素。不要想,知道:是否会对其进行分析?

如果没有,我会说更大的问题是设计的清晰度和可读性,而不是引入新代码来维护。碰巧的是,如果你正在使用Swing,那么有一个库可以完全你正在尝试做什么,称为SwingWorker

答案 3 :(得分:0)

查看java.util.concurrent.ConcurrentLinkedQueuejava.util.concurrent.ConcurrentHashMapjava.util.concurrent.ConcurrentSkipListSet。他们可能会做你需要的。例如,ConcurrentSkipListSet声称containsaddremove操作的预期平均 log(n)时间成本及其插入,删除和访问操作由多个线程安全地同时执行。“

答案 4 :(得分:0)

您可能想要查看的其他两种模式是

  • 每个线程都有自己的集合,在轮询时它返回集合并创建一个新集合,因此集合只保存轮询之间的待处理项。线程需要保护其集合上的操作,但线程之间没有争用。这是阻塞(当UI线程从中获取更新时,每个线程都无法添加到其集合中),但可以减少争用(线程之间没有争用)。

  • 每个线程都有自己的集合,并将结果附加到使用Lock.tryLock()保护的公共队列。如果线程无法获取锁定,则线程继续处理。这使得线程不太可能阻止等待共享队列。