什么时候比LinkedBlockingQueue更喜欢ArrayBlockingQueue

何时在LinkedBlockingQueueArrayBlockingQueue中使用哪种数据结构:

  • 您想要高效的读写
  • 应该具有较少的内存占用量

  • 尽管存在类似的问题,但它并未突出这样一个事实:应优先选择哪个?

    链接:
  • Java: ArrayBlockingQueue vs. LinkedBlockingQueue
  • What is the Difference between ArrayBlockingQueue and LinkedBlockingQueue
  • 最佳答案

    Boris Spider已经概述了ArrayBlockingQueueLinkedBlockingQueue之间最明显的区别-前者始终是有界的,而后者可以是无界的。

    因此,如果您需要无限制的阻塞队列,则LinkedBlockingQueue工具箱中的最佳选择是LinkedTransferQueue或用作BlockingQueuejava.util.concurrent

    但是,假设您需要一个有限的阻塞队列。
    最后,您应该基于对实际工作负载进行模拟的广泛实验来选择一种实现。
    不过,以下是一些注释,可以帮助您进行选择或解释实验结果:

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

  • 根据您的用例以及您对性能有多大的关注,您可能还希望查看java.util.concurrent之外的内容,并考虑使用Disruptor(一种速度非常快,但具有一定专业性的有界非阻塞环形缓冲区)或JCTools(各种有界或具有无限保证的无限制队列,具体取决于生产者和消费者的数量)。

    10-08 16:01