什么时候比LinkedBlockingQueue
更喜欢ArrayBlockingQueue
?
何时在LinkedBlockingQueue
和ArrayBlockingQueue
中使用哪种数据结构:
尽管存在类似的问题,但它并未突出这样一个事实:应优先选择哪个?
链接:
最佳答案
Boris Spider已经概述了ArrayBlockingQueue
和LinkedBlockingQueue
之间最明显的区别-前者始终是有界的,而后者可以是无界的。
因此,如果您需要无限制的阻塞队列,则LinkedBlockingQueue
工具箱中的最佳选择是LinkedTransferQueue
或用作BlockingQueue
的java.util.concurrent
。
但是,假设您需要一个有限的阻塞队列。
最后,您应该基于对实际工作负载进行模拟的广泛实验来选择一种实现。
不过,以下是一些注释,可以帮助您进行选择或解释实验结果:
ArrayBlockingQueue
可以使用可配置的(开/关)调度公平性策略来创建。如果您需要公平性或想要避免生产者/消费者饥饿,那么这很好,但是这会浪费您的吞吐量。 ArrayBlockingQueue
预分配了其后备数组,因此它在使用过程中不会分配节点,但是会立即占用相当大的内存块,如果您的内存碎片化,则可能会出现问题。 ArrayBlockingQueue
应该在性能上具有较小的可变性,因为它总体上具有较少的运动部件,它使用更简单且不太复杂的单锁算法,在使用过程中不创建节点,并且其缓存行为应相当一致。 LinkedBlockingQueue
应该具有更好的吞吐量,因为它为头部和尾部使用了单独的锁。 LinkedBlockingQueue
不会预分配节点,这意味着它的内存占用空间将大致与其大小匹配,但是这也意味着它将招致一些工作,以分配和释放节点。 LinkedBlockingQueue
可能具有较差的缓存行为,这可能会影响其自身的性能,还会由于错误共享而影响其他组件的性能。 根据您的用例以及您对性能有多大的关注,您可能还希望查看
java.util.concurrent
之外的内容,并考虑使用Disruptor(一种速度非常快,但具有一定专业性的有界非阻塞环形缓冲区)或JCTools(各种有界或具有无限保证的无限制队列,具体取决于生产者和消费者的数量)。