java 什么时候比 ArrayBlockingQueue 更喜欢 LinkedBlockingQueue?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35967792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:49:09  来源:igfitidea点击:

When to prefer LinkedBlockingQueue over ArrayBlockingQueue?

javamultithreadingconcurrencyblockingqueue

提问by Vaibhav Gupta

When to prefer LinkedBlockingQueueover ArrayBlockingQueue?

当喜欢LinkedBlockingQueueArrayBlockingQueue

Which data structure to use among LinkedBlockingQueueand ArrayBlockingQueuewhen:

其数据结构中使用LinkedBlockingQueueArrayBlockingQueue时:

  1. You want an efficient read and write
  2. should have lesser memory footprints
  1. 您想要高效的读写
  2. 应该有更少的内存占用

Although there is a similar question but it does not highlight the fact that which should be preferred?

虽然有一个类似的问题,但它并没有强调应该首选哪个?

Links:

链接:

回答by Dimitar Dimitrov

Boris the Spider has already outlined the most visible difference between ArrayBlockingQueueand LinkedBlockingQueue- the former is always bounded, while the latter can be unbounded.

鲍里斯蜘蛛已经概述了ArrayBlockingQueue和之间最明显的区别LinkedBlockingQueue——前者总是有界的,而后者可以是无界的。

So in case you need an unbounded blocking queue, LinkedBlockingQueueor a LinkedTransferQueueused as a BlockingQueueare your best bets from the java.util.concurrenttoolbox.

因此,如果您需要一个无限的阻塞队列,LinkedBlockingQueue或者LinkedTransferQueue用作 aBlockingQueuejava.util.concurrent工具箱中的最佳选择。

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:

但是假设您需要一个有界阻塞队列。最后,您应该根据对实际工作负载的模拟进行大量实验来选择一种实现。不过,这里有一些注释可以帮助您做出选择或解释实验结果:

  • ArrayBlockingQueuecan 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.
  • ArrayBlockingQueuepre-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.
  • ArrayBlockingQueueshould 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.
  • LinkedBlockingQueueshould have better throughput, because it uses separate locks for the head and the tail.
  • LinkedBlockingQueuedoes 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.
  • LinkedBlockingQueuewill probably have worse cache behavior, which may affect its own performance, but also the performance of other components due to false sharing.
  • ArrayBlockingQueue可以使用可配置的(开/关)调度公平策略创建。如果您需要公平或想要避免生产者/消费者饥饿,这很好,但它会花费您的吞吐量。
  • ArrayBlockingQueue预先分配其后备数组,因此它在使用期间不会分配节点,但它会立即占用可能是相当大的内存块,如果您的内存碎片化,这可能是一个问题。
  • ArrayBlockingQueue应该具有较小的性能可变性,因为它总体上具有较少的移动部件,它使用更简单和不太复杂的单锁算法,它在使用过程中不会创建节点,并且它的缓存行为应该相当一致。
  • LinkedBlockingQueue应该有更好的吞吐量,因为它对头部和尾部使用单独的锁。
  • LinkedBlockingQueue不预先分配节点,这意味着它的内存占用将与其大小大致匹配,但这也意味着它会产生一些分配和释放节点的工作。
  • LinkedBlockingQueue可能会有更糟糕的缓存行为,这可能会影响其自身的性能,但也会由于错误共享而影响其他组件的性能。

Depending on your use-case and how much do you care about performance, you may also want to look outside of java.util.concurrentand 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).

根据您的用例以及您对性能的关心程度,您可能还想看看外部java.util.concurrent并考虑Disruptor(一种非常快但有些专门的有界非阻塞环形缓冲区)或JCTools(各种有界或无界队列具有不同的保证取决于生产者和消费者的数量)。

回答by Boris the Spider

From the JavaDoc for ArrayBlockingQueue

来自JavaDoc forArrayBlockingQueue

A boundedblocking queue backed by an array.

阻塞队列背靠阵列。

Emphasis mine

强调我的

From the JavaDoc for LinkedBlockingQueue:

来自JavaDoc 的LinkedBlockingQueue

An optionally-boundedblocking queue based on linked nodes.

基于链接节点的可选有界阻塞队列。

Emphasis mine

强调我的

So if you need a boundedqueue you can use either, if you need an unboundedqueue you must use LinkedBlockingQueue.

因此,如果您需要一个有界队列,则可以使用其中任何一个,如果您需要一个无界队列,则必须使用LinkedBlockingQueue.

For a boundedqueue, then you would need to benchmark to work out which is better.

对于有队列,您需要进行基准测试以确定哪个更好。