什么时候更喜欢LinkedBlockingQueue而不是ArrayBlockingQueue?

时间:2016-03-13 07:37:14

标签: java multithreading concurrency blockingqueue

何时更喜欢LinkedBlockingQueue而不是ArrayBlockingQueue

LinkedBlockingQueueArrayBlockingQueue之间使用哪种数据结构:

  1. 您想要高效的读写
  2. 应该有更少的记忆足迹
  3. 虽然有一个类似的问题,但它没有突出应该首选的事实?

    链接:

3 个答案:

答案 0 :(得分:48)

鲍里斯蜘蛛已经概述了ArrayBlockingQueueLinkedBlockingQueue之间最明显的区别 - 前者总是有界的,而后者可以是无界的。

因此,如果您需要一个无限制的阻止队列,LinkedBlockingQueue或用作LinkedTransferQueue的{​​{1}}是BlockingQueue工具箱中最好的选择。

但是,让我们说你需要一个有界的阻塞队列。 最后,您应该选择基于广泛试验的实现,模拟您的实际工作负载。 不过,这里有一些注释可以帮助您选择或解释实验结果:

    可以使用可配置(开/关)调度公平策略创建
  • java.util.concurrent。如果你需要公平或想要避免生产者/消费者的饥饿,这是很好的,但它会花费你的吞吐量。
  • ArrayBlockingQueue预分配其后备阵列,因此它在使用期间不会分配节点,但它会立即占用相当大的内存块,如果你的内存是碎片。
  • ArrayBlockingQueue应该具有较少的性能可变性,因为它总体上具有较少的移动部件,它使用更简单且不太复杂的单锁算法,它在使用期间不创建节点,并且其缓存行为应该是相当一致。
  • ArrayBlockingQueue应该有更好的吞吐量,因为它对头部和尾部使用单独的锁。
  • LinkedBlockingQueue没有预先分配节点,这意味着它的内存占用量将大致与其大小相匹配,但这也意味着它将产生一些分配和释放节点的工作。
  • LinkedBlockingQueue可能会有更糟糕的缓存行为,这可能会影响其自身的性能,但也可能会因错误共享而影响其他组件的性能。

根据您的使用情况以及您对性能的关注程度,您可能还希望在LinkedBlockingQueue之外查看并考虑Disruptor(速度非常快,但有些特殊的有界非阻塞环缓冲区)或JCTools(各种有界或无界的队列,具有不同的保证,具体取决于生产者和消费者的数量)。

答案 1 :(得分:10)

来自JavaDoc for ArrayBlockingQueue

  

由数组支持的有界阻止队列。

强调我的

来自JavaDoc for LinkedBlockingQueue

  

基于链接节点的可选绑定阻塞队列。

强调我的

因此,如果您需要有界队列,则可以使用其中任何一个,如果您需要无界队列,则必须使用LinkedBlockingQueue

对于有界队列,那么您需要进行基准测试以确定哪个更好。

答案 2 :(得分:0)

他们都实施BlockingQueue。顾名思义,arrayBlockingQueueArray支持,而LinkedBlockingQueuelinked list支持。

选择哪一个应与在ArrayListLinkedList

之间选择的原因相同

将元素添加到ArrayBlockingQueue应该更快,因为它意味着只设置对后备Object数组元素的引用,而向LinkedBlockingQueue添加元素意味着创建Node并设置其项目prevnext字段。此外,当我们从LinkedBlockingQueue中删除元素时,删除的节点会变成垃圾,这可能会影响应用程序的性能。