问题描述
什么时候比ArrayBlockingQueue
更喜欢LinkedBlockingQueue
?
在以下情况下,在LinkedBlockingQueue
和ArrayBlockingQueue
中使用哪种数据结构:
- 您想要有效的读写
- 应该减少内存占用量
尽管存在类似的问题,但并未突出哪个应该被优先考虑的事实?
链接:
蜘蛛网鲍里斯(Boris)已经概述了ArrayBlockingQueue
和LinkedBlockingQueue
之间最明显的区别-前者始终是有界的,而后者可以是无界的. /p>
因此,如果您需要无限制的阻塞队列,则java.util.concurrent
工具箱中的最佳选择是LinkedBlockingQueue
或用作BlockingQueue
的LinkedTransferQueue
.
但是,假设您需要一个有界的阻塞队列.最后,您应该基于对实际工作负载进行模拟的广泛实验来选择一种实现.不过,以下是一些注释,可以帮助您进行选择或解释实验结果:
- 可以使用可配置的(开/关)调度公平性策略创建
-
ArrayBlockingQueue
.如果您需要公平或希望避免生产者/消费者饥饿,那么这很好,但是这会浪费您的生产量. -
ArrayBlockingQueue
预分配其后备数组,因此它在使用期间不会分配节点,但是会立即占用相当大的内存块,如果您的内存碎片化,则可能会出现问题. -
ArrayBlockingQueue
应该在性能上具有较小的可变性,因为它总体上具有较少的活动部件,它使用更简单且不太复杂的单锁算法,在使用过程中不创建节点,并且其缓存行为应相当一致 -
LinkedBlockingQueue
应该具有更好的吞吐量,因为它为头部和尾部使用了单独的锁. -
LinkedBlockingQueue
不会预分配节点,这意味着它的内存占用量将大致与其大小匹配,但是这也意味着它将为分配和释放节点带来一些工作. -
LinkedBlockingQueue
可能具有较差的缓存行为,这可能会影响其自身的性能,还会由于错误共享而影响其他组件的性能.
根据您的用例以及您对性能有多大的关注,您可能还希望查看java.util.concurrent
以外的地方并考虑 Disruptor (异常快,但有些专门的有界非阻塞环形缓冲区)或 JCTools (各种有界或无界队列,它们根据生产者和消费者的数量而有不同的保证).
When to prefer LinkedBlockingQueue
over ArrayBlockingQueue
?
Which data structure to use among LinkedBlockingQueue
and ArrayBlockingQueue
when:
- You want an efficient read and write
- should have lesser memory footprints
Although there is a similar question but it does not highlight the fact that which should be preferred?
Links:
- Java: ArrayBlockingQueue vs. LinkedBlockingQueue
- What is the Difference between ArrayBlockingQueue and LinkedBlockingQueue
Boris the Spider has already outlined the most visible difference between ArrayBlockingQueue
and LinkedBlockingQueue
- the former is always bounded, while the latter can be unbounded.
So in case you need an unbounded blocking queue, LinkedBlockingQueue
or a LinkedTransferQueue
used as a BlockingQueue
are your best bets from the java.util.concurrent
toolbox.
But let's say you need a bounded blocking queue.In the end, you should choose an implementation based on extensive experimenting with a simulation of your real-world workload.Nevertheless, here are some notes that can help you with your choice or with interpreting the results from the experiment:
ArrayBlockingQueue
can be created with a configurable (on/off) scheduling fairness policy. This is great if you need fairness or want to avoid producer/consumer starvation, but it will cost you in throughput.ArrayBlockingQueue
pre-allocates its backing array, so it doesn't allocate nodes during its usage, but it immediately takes what can be a considerable chunk of memory, which can be a problem if your memory is fragmented.ArrayBlockingQueue
should have less variability in performance, because it has less moving parts overall, it uses a simpler and less-sophisticated single-lock algorithm, it does not create nodes during usage, and its cache behavior should be fairly consistent.LinkedBlockingQueue
should have better throughput, because it uses separate locks for the head and the tail.LinkedBlockingQueue
does not pre-allocate nodes, which means that its memory footprint will roughly match its size, but it also means that it will incur some work for allocation and freeing of nodes.LinkedBlockingQueue
will probably have worse cache behavior, which may affect its own performance, but also the performance of other components due to false sharing.
Depending on your use-case and how much do you care about performance, you may also want to look outside of java.util.concurrent
and consider Disruptor (an exceptionally fast, but somewhat specialized bounded non-blocking ring buffer) or JCTools (a variety of bounded or unbounded queues with different guarantees depending on the number of producers and consumers).
这篇关于什么时候更喜欢LinkedBlockingQueue而不是ArrayBlockingQueue?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!