何时更喜欢LinkedBlockingQueue
而不是ArrayBlockingQueue
?
在LinkedBlockingQueue
和ArrayBlockingQueue
之间使用哪种数据结构:
虽然有一个类似的问题,但它没有突出应该首选的事实?
链接:
答案 0 :(得分:48)
鲍里斯蜘蛛已经概述了ArrayBlockingQueue
和LinkedBlockingQueue
之间最明显的区别 - 前者总是有界的,而后者可以是无界的。
因此,如果您需要一个无限制的阻止队列,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
。顾名思义,arrayBlockingQueue
由Array
支持,而LinkedBlockingQueue
由linked list
支持。
选择哪一个应与在ArrayList
和LinkedList
将元素添加到ArrayBlockingQueue
应该更快,因为它意味着只设置对后备Object数组元素的引用,而向LinkedBlockingQueue
添加元素意味着创建Node
并设置其项目prev
和next
字段。此外,当我们从LinkedBlockingQueue
中删除元素时,删除的节点会变成垃圾,这可能会影响应用程序的性能。