【问题标题】:What collection supports multiple simultaneous insertions?什么集合支持多个同时插入?
【发布时间】:2010-06-22 12:29:12
【问题描述】:

我们正在开发一个带有多个工作线程的 Java 应用程序。这些线程必须将大量计算结果传递给我们的 UI 线程。结果的传递顺序无关紧要。

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

是否有支持同时插入的数据结构,每次插入都在恒定时间内完成?

谢谢,

马丁

【问题讨论】:

    标签: java performance multithreading data-structures


    【解决方案1】:

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

    ArrayBlockingQueue 更适合较低的争用,空间开销较低。

    编辑:虽然这不是你要求的。同时插入?您可能希望给每个线程一个输出队列(例如,ArrayBlockingQueue),然后让 UI 线程轮询单独的队列。但是,我认为您会发现上述两个 Queue 实现之一就足够了。

    【讨论】:

    • +1:这绝对是并发Queue 实现的情况。
    • @Andrzej:对我来说,这听起来更像是过早优化。
    • @Michael 不是真的 - 在可能要放入大量数据的数据结构上指定恒定时间插入是完全正常的,如果您不使用库中的并发队列,你有更多的代码要编写并且更难测试以获得具有正确行为的东西。 OP 或这篇文章中没有任何关于优化的内容,只是要求中的正确性。
    • @Pete:对于队列而言,恒定时间插入相当简单,所以这不是真正的问题。我认为这个问题主要是关于并发的。使用同步集合是解决这个问题的简单方法,当队列只包含 results 而不是直接参与计算时,担心锁争用对我来说似乎是过早的优化。
    【解决方案2】:

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

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

    【讨论】:

    • 你是对的,但是由于正在计算大量结果,并且每次计算都非常快,我认为可能会有冲突。另外,我只是好奇是否存在这样的数据集合:)
    • @Martin:确认,不要“图”。在 VisualVM 的线程视图中查看您的应用程序,看看它们实际花费了多少时间等待锁定。如果它真的很重要,为什么不在提交结果之前让每个线程在更大的包中进行计算呢?它还以其他方式减少开销。
    【解决方案3】:

    退后一步,评估性能是否是此处的关键设计考虑因素。不要思考,知道:分析是否支持它?

    如果不是,我想说一个更大的问题是设计的清晰度和可读性,而不是引入新的代码来维护。碰巧的是,如果您使用的是 Swing,则有一个库可以完全执行您正在尝试执行的操作,称为 SwingWorker

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您可能想要查看的另外两种模式是

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

        • 每个线程都有自己的集合,并将结果附加到使用 Lock.tryLock() 保护的公共队列。如果获取锁失败,线程继续处理。这降低了线程阻塞等待共享队列的可能性。

        【讨论】:

        • 这个答案还有更多内容吗?
        • @Ben 我已经从我的 IDE 切换到 tab+enter 会缩进并换行而不是提交
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-13
        • 2012-09-24
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        相关资源
        最近更新 更多