java 为什么 ArrayBlockingQueue 被称为有界队列而 LinkedBlockingQueue 被称为无界阻塞队列?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11830664/
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
Why the ArrayBlockingQueue is called a bounded queue while a LinkedBlockingQueue is called an unbounded blocking queue?
提问by Geek
As far as I know both the linked list and array can grow without bounds or am I wrong ? But when I have gone through the documentation in the Executor ServiceI see this :
据我所知,链表和数组都可以无限增长,还是我错了?但是当我浏览了 Executor Service 中的文档时,我看到了这一点:
Unbounded queues. Using an unbounded queue (for example a LinkedBlockingQueue without a predefined capacity) will cause new tasks to wait in the queue when all corePoolSize threads are busy. Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn't have any effect.)
无界队列。使用无界队列(例如,没有预定义容量的 LinkedBlockingQueue)将导致新任务在所有 corePoolSize 线程都忙时在队列中等待。因此,不会创建超过 corePoolSize 的线程。(因此,maximumPoolSize 的值没有任何影响。)
So does the Unbounded Queue
property changes when the LinkedBlockingQueue
has a defined capacity ?
那么Unbounded Queue
当LinkedBlockingQueue
具有定义的容量时,属性会发生变化吗?
And this written for ArrayBlockingQueue
:
这是为ArrayBlockingQueue
:
Bounded queues. A bounded queue (for example, an ArrayBlockingQueue) helps prevent resource exhaustion when used with finite maximumPoolSizes, but can be more difficult to tune and control. Queue sizes and maximum pool sizes may be traded off for each other: Using large queues and small pools minimizes CPU usage, OS resources, and context-switching overhead, but can lead to artificially low throughput. If tasks frequently block (for example if they are I/O bound), a system may be able to schedule time for more threads than you otherwise allow. Use of small queues generally requires larger pool sizes, which keeps CPUs busier but may encounter unacceptable scheduling overhead, which also decreases throughput.
有界队列。有界队列(例如,ArrayBlockingQueue)在与有限的 maximumPoolSizes 一起使用时有助于防止资源耗尽,但可能更难以调整和控制。队列大小和最大池大小可以相互权衡:使用大队列和小池可以最大限度地减少 CPU 使用率、操作系统资源和上下文切换开销,但会导致人为地降低吞吐量。如果任务频繁阻塞(例如,如果它们受 I/O 限制),则系统可能能够为比您允许的更多线程安排时间。使用小队列通常需要更大的池大小,这会使 CPU 更忙,但可能会遇到不可接受的调度开销,这也会降低吞吐量。
回答by Andrzej Doyle
Why do you think that an ArrayBlockingQueue
can grow without bounds? From its own documentation:
为什么你认为一个ArrayBlockingQueue
可以无限增长?从它自己的文档:
This is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. Once created, the capacity cannot be increased. Attempts to put an element into a full queue will result in the operation blocking; attempts to take an element from an empty queue will similarly block.
这是一个经典的“有界缓冲区”,其中一个固定大小的数组保存由生产者插入并由消费者提取的元素。一旦创建,容量就不能增加。尝试将元素放入已满队列将导致操作阻塞;尝试从空队列中获取元素也会类似地阻塞。
In other words, once it gets full, it's full - it doesn't grow.
换句话说,一旦它满了,它就满了——它不会增长。
Are you getting confused with an ArrayList
by any chance - which is also backed by an array, but which expands this as required?
您是否有ArrayList
任何机会与 an 混淆- 它也由数组支持,但它会根据需要扩展它?
So does the Unbounded Queue property changes when the LinkedBlockingQueue has a defined capacity ?
那么当 LinkedBlockingQueue 具有定义的容量时,Unbounded Queue 属性会发生变化吗?
Yes, hence why it's described as "optionally-bounded" in its Javadocs. Furthermore, the docs state that (emphasis mine):
是的,因此为什么它在其Javadocs 中被描述为“可选有界” 。此外,文档指出(强调我的):
The optional capacity bound constructor argument serves as a way to prevent excessive queue expansion. The capacity, if unspecified, is equal to Integer.MAX_VALUE. Linked nodes are dynamically created upon each insertion unless this would bring the queue above capacity.
可选的容量绑定构造函数参数是一种防止队列过度扩展的方法。如果未指定,容量等于 Integer.MAX_VALUE。链接节点在每次插入时动态创建,除非这会使队列超过容量。
回答by JB Nizet
The javadoc for LinkedBlockingQueuesays:
An optionally-bounded blocking queue based on linked nodes.[...]
The optional capacity bound constructor argument serves as a way to prevent excessive queue expansion. The capacity, if unspecified, is equal to Integer.MAX_VALUE.
基于链接节点的可选有界阻塞队列。[...]
可选的容量绑定构造函数参数是一种防止队列过度扩展的方法。如果未指定,容量等于 Integer.MAX_VALUE。
The javadoc of ArrayBlockingQueuesays:
A bounded blocking queue backed by an array.[...]
This is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. Once created, the capacity cannot be increased
由数组支持的有界阻塞队列。[...]
这是一个经典的“有界缓冲区”,其中一个固定大小的数组保存由生产者插入并由消费者提取的元素。一旦创建,容量无法增加
So, a LinkedBlockingQueue can be bounded or unbounded, whereas an ArrayBlockingQueue is always bounded.
因此,LinkedBlockingQueue 可以是有界或无界的,而 ArrayBlockingQueue 始终是有界的。
回答by Peter Lawrey
As far as I know both the linked list and array can grow without bounds or am I wrong
据我所知,链表和数组都可以无限增长,或者我错了
A linked list as an unlimited size. An array has fixed size. An ArrayList wraps an array and replaces it when it needs a bigger one.
一个无限大小的链表。数组具有固定大小。ArrayList 包装一个数组并在需要更大的数组时替换它。
So does the Unbounded Queue property changes when the LinkedBlockingQueue has a defined capacity
当 LinkedBlockingQueue 具有定义的容量时,Unbounded Queue 属性也会发生变化
When LinkedBlockingQueue has a maximum capacity, it is bounded but it not used this way by default.
当 LinkedBlockingQueue 具有最大容量时,它是有界的,但默认情况下不使用这种方式。
回答by John B
From the documentataion for ArrayBlockingQueue
来自ArrayBlockingQueue的文档
A bounded blocking queue backed by an array. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.
由数组支持的有界阻塞队列。此队列对元素 FIFO(先进先出)进行排序。队列的头部是在队列中停留时间最长的那个元素。队列的尾部是在队列中停留时间最短的那个元素。新元素插入队列尾部,队列检索操作获取队列头部元素。
If you notice all the constructors of ArrayBlockingQueue take a capacity because this class was designed to be bounded. This choice was made because if you want a concurrent queue, you probably don't want the overhead that comes with resizing an ArrayList. Hence, if you want an unbounded queue LinkedBlockingQueue is a better option since it does not involve this overhead.
如果您注意到 ArrayBlockingQueue 的所有构造函数都占用一个容量,因为此类被设计为有界的。做出这个选择是因为如果你想要一个并发队列,你可能不想要调整 ArrayList 大小带来的开销。因此,如果您想要一个无界队列 LinkedBlockingQueue 是更好的选择,因为它不涉及此开销。
回答by wannibar
other answer is very right! I provide another way to explain. well, I also get confused by the term "unbound and bound" passed. you can look at the source code blew.
其他答案很对!我提供另一种解释方式。好吧,我也对通过的“未绑定和绑定”一词感到困惑。你可以看看源代码自爆。
/** 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;
from the source code, we can see the array is final, so we can not resize the array. if use LinkedBlockingQueue, we can always add more elements...and in the source code, the next reference is not final. NOTE, in theory, LinkedBlockingQueue is not unbounded. because it can only store MAX_INTEGER minus 8 elements. from javadoc, the unbounded queue is PriorityBlockingQueue. but the PriorityBlockingQueue also can only store MAX_INTEGER -8 elements. so i think there is no perfect unbounded queue...
从源代码中,我们可以看到数组是final,所以我们不能调整数组的大小。如果使用 LinkedBlockingQueue,我们总是可以添加更多元素......并且在源代码中,下一个引用不是最终的。注意,理论上,LinkedBlockingQueue 不是无界的。因为它只能存储 MAX_INTEGER 减去 8 个元素。来自 javadoc,无界队列是 PriorityBlockingQueue。但是 PriorityBlockingQueue 也只能存储 MAX_INTEGER -8 个元素。所以我认为没有完美的无界队列......