何时更喜欢 LinkedBlockingQueue
而不是 ArrayBlockingQueue
?
LinkedBlockingQueue
和 ArrayBlockingQueue
之间使用哪种数据结构时:
- 您想要高效的读写
- 应该有更少的内存占用
虽然有一个类似的问题,但它并没有强调应该首选哪个?
链接:
最佳答案
蜘蛛鲍里斯已经概述了 ArrayBlockingQueue
之间最明显的区别。和 LinkedBlockingQueue
- 前者总是有界的,而后者可以是无界的。
因此,如果您需要一个无界阻塞队列,LinkedBlockingQueue
或 LinkedTransferQueue
用作BlockingQueue
java.util.concurrent
是您最好的选择工具箱。
但是假设您需要一个有界阻塞队列。 最后,您应该根据对真实工作负载的模拟进行大量试验来选择实现。 不过,这里有一些注释可以帮助您做出选择或解释实验结果:
-
ArrayBlockingQueue
可以使用可配置的(开/关)调度公平策略来创建。如果您需要公平或想要避免生产者/消费者饥饿,这非常好,但它会降低您的吞吐量。 -
ArrayBlockingQueue
预先分配它的后备数组,因此它在使用期间不会分配节点,但它会立即占用相当大的内存块,如果您的内存碎片化,这可能是个问题。 -
ArrayBlockingQueue
性能上的可变性应该更小,因为它的整体移动部件更少,它使用更简单且不太复杂的单锁算法,它在使用过程中不会创建节点,并且它的缓存行为应该相当一致。 -
LinkedBlockingQueue
应该有更好的吞吐量,因为它对头部和尾部使用单独的锁。 -
LinkedBlockingQueue
不预先分配节点,这意味着它的内存占用将大致匹配它的大小,但这也意味着它会产生一些分配和释放节点的工作。 -
LinkedBlockingQueue
可能会有更糟糕的缓存行为,这可能会影响自己的性能,但也会因错误共享而影响其他组件的性能。
根据您的用例以及您对性能的关注程度,您可能还想查看 java.util.concurrent
之外的内容。并考虑Disruptor (一个非常快,但有些特殊的有界非阻塞环形缓冲区)或JCTools (各种有界或无界队列,根据生产者和消费者的数量提供不同的保证)。
关于java - 何时更喜欢 LinkedBlockingQueue 而不是 ArrayBlockingQueue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35967792/