何时更喜欢LinkedBlockingQueue而不是ArrayBlockingQueue?

什么时候更喜欢?LinkedBlockingQueueArrayBlockingQueue

在以下情况下使用哪种数据结构:LinkedBlockingQueueArrayBlockingQueue

  1. 您想要高效的读写功能
  2. 应具有较少的内存占用量

虽然有一个类似的问题,但它并没有突出一个事实,即哪个应该是首选的?

链接:


答案 1

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

因此,如果您需要一个无限的阻塞队列,或者用作工具箱中的最佳选择。LinkedBlockingQueueLinkedTransferQueueBlockingQueuejava.util.concurrent

但是,假设您需要一个有界阻塞队列。最后,您应该根据对实际工作负载的模拟进行的广泛试验来选择实现。尽管如此,这里有一些注意事项可以帮助您进行选择或解释实验结果:

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

根据您的用例以及您对性能的关心程度,您可能还希望查看Disruptor(一种非常快速,但有些专门的有界非阻塞环形缓冲区)或JCTools(各种有界或无界队列,根据生产者和使用者的数量具有不同的保证)。java.util.concurrent


答案 2

From the JavaDoc for ArrayBlockingQueue

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

强调我的

来自 JavaDoc for LinkedBlockingQueue

基于链接节点的可选有界阻塞队列。

强调我的

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

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


推荐