繁体   English   中英

为什么ArrayBlockingQueue被称为有界队列而LinkedBlockingQueue被称为无界阻塞队列?

[英]Why the ArrayBlockingQueue is called a bounded queue while a LinkedBlockingQueue is called an unbounded blocking queue?

据我所知,链表和数组都可以无限制地增长,或者我错了吗? 但是当我查看Executor Service中文档时,我看到了:

无限的队列。 使用无界队列(例如,没有预定义容量的LinkedBlockingQueue)将导致新任务在所有corePoolSize线程忙时在队列中等待。 因此,只会创建corePoolSize线程。 (而且maximumPoolSize的值因此没有任何影响。)

LinkedBlockingQueue具有已定义的容量时, Unbounded Queue属性是否会更改?

这是为ArrayBlockingQueue写的:

有界的队列。 有限队列(例如,ArrayBlockingQueue)在与有限maximumPoolSizes一起使用时有助于防止资源耗尽,但可能更难以调整和控制。 队列大小和最大池大小可以相互交换:使用大型队列和小型池最小化CPU使用率,OS资源和上下文切换开销,但可能导致人为的低吞吐量。 如果任务经常阻塞(例如,如果它们是I / O绑定的),系统可能能够为您提供比您允许的更多线程的时间。 使用小队列通常需要更大的池大小,这会使CPU更加繁忙,但可能会遇到不可接受的调度开销,这也会降低吞吐量。

为什么你认为ArrayBlockingQueue可以ArrayBlockingQueue地增长? 从它自己的文件

这是一个经典的“有界缓冲区”,其中固定大小的数组包含由生产者插入并由消费者提取的元素。 一旦创建,容量就无法增加。 尝试将元素放入完整队列将导致操作阻塞; 尝试从空队列中获取元素同样会阻塞。

换句话说,一旦它变满,它就会充满 - 它不会增长。

您是否有机会与ArrayList混淆 - 这也是由数组支持,但是根据需要扩展它?

当LinkedBlockingQueue具有已定义的容量时,Unbounded Queue属性是否会更改?

是的,因此它在Javadocs中被描述为“可选 - 有界”。 此外,文档说明(强调我的):

可选的容量绑定构造函数参数用作防止过多队列扩展的方法。 如果未指定,则容量等于Integer.MAX_VALUE。 每次插入时都会动态创建链接节点, 除非这会使队列超出容量

LinkedBlockingQueuejavadoc说:

基于链接节点的可选绑定阻塞队列。[...]

可选的容量绑定构造函数参数用作防止过多队列扩展的方法。 如果未指定,则容量等于Integer.MAX_VALUE。

ArrayBlockingQueuejavadoc说:

由数组支持的有界阻塞队列。[...]

这是一个经典的“有界缓冲区”,其中固定大小的数组包含由生产者插入并由消费者提取的元素。 一旦创建,容量就无法增加

因此,LinkedBlockingQueue可以是有界的,也可以是无界的,而ArrayBlockingQueue总是有界的。

据我所知,链表和数组都可以无限制地增长,或者我错了

链表作为无限大小。 数组具有固定大小。 ArrayList包装一个数组,并在需要更大的数组时替换它。

当LinkedBlockingQueue具有已定义的容量时,Unbounded Queue属性也会更改

当LinkedBlockingQueue具有最大容量时,它是有界的,但默认情况下不以这种方式使用。

来自ArrayBlockingQueue的documentataion

由数组支持的有界阻塞队列。 此队列对元素FIFO(先进先出)进行排序。 队列的头部是队列中最长时间的元素。 队列的尾部是队列中最短时间的元素。 新元素插入队列的尾部,队列检索操作获取队列头部的元素。

如果您注意到ArrayBlockingQueue的所有构造函数都占用了一个容量,因为这个类被设计为有界。 之所以做出这样的选择,是因为如果你想要一个并发队列,你可能不希望调整ArrayList的大小。 因此,如果你想要一个无界的队列,LinkedBlockingQueue是一个更好的选择,因为它不涉及这种开销。

其他答案是对的! 我提供另一种解释方式。 好吧,我也对“未绑定和绑定”一词感到困惑。 你可以看看源代码自爆。

    /** The queued items */
final Object[] items;

/** items index for next take, poll, peek or remove */
int takeIndex;

/** items index for next put, offer, or add */
int putIndex;

/** Number of elements in the queue */
int count;

从源代码中,我们可以看到数组是final的 ,所以我们无法调整数组的大小。 如果使用LinkedBlockingQueue,我们总是可以添加更多元素......并且在源代码中,下一个引用不是最终的。 注意,理论上,LinkedBlockingQueue不是无界限的。 因为它只能存储MAX_INTEGER减去8个元素。 从javadoc,无界队列是PriorityBlockingQueue。 但PriorityBlockingQueue也只能存储MAX_INTEGER -8元素。 所以我认为没有完美无界的队列......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM