一尘不染

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

java

当喜欢LinkedBlockingQueueArrayBlockingQueue

何时LinkedBlockingQueue以及ArrayBlockingQueue何时使用哪种数据结构:

  1. 您想要高效的读写
  2. 应该具有更少的内存占用

尽管存在类似的问题,但它并没有突出表明应该优先选择哪个事实?


阅读 314

收藏
2020-12-03

共1个答案

一尘不染

蜘蛛侠鲍里斯(Boris the
Spider)已经概述了ArrayBlockingQueue和之间最明显的区别LinkedBlockingQueue-前者始终是有界的,而后者可以是无界的。

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

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

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

根据您的使用情况,并做了多少你关心性能,你可能还需要的外观之外java.util.concurrent,并考虑干扰物(一个非常快,但有些专门界无阻塞环形缓冲区)或JCTools(各种界或无界根据生产者和消费者的数量,具有不同保证的队列)。

2020-12-03