- 在哪些场景中最好使用ArrayBlockingQueue?什么时候使用LinkedBlockingQueue更好?
- 如果LinkedBlockingQueue的默认容量等于MAX Integer,那么将其用作具有默认容量的BlockingQueue是否真的有所帮助?
ArrayBlockingQueue
使用不会改变大小的数组作为后端。将容量设置为Integer.MAX_VALUE
将创建一个非常大的数组,占用很高的空间成本。
ArrayBlockingQueue
总是有界的。
LinkedBlockingQueue
在达到capacity
之前动态创建节点。默认情况下,这个值为Integer.MAX_VALUE
。使用这样一个大容量没有额外的空间成本。
LinkedBlockingQueue
可选地是有界的。
ArrayBlockingQueue :
ArrayBlockingQueue是一个有界的、阻塞队列,它在内部使用数组存储元素。由于它是有界的,意味着它不能无限制地存储元素。它同时只能存储一定数量的元素,这个上限在初始化时设置,并且不能更改。
LinkedBlockingQueue
LinkedBlockingQueue将元素在其内部使用链式结构进行存储(链接节点)。如果需要,该链式结构可以选择具有上限。如果未指定上限,则使用Integer.MAX_VALUE作为上限。
相似之处
ArrayBlockingQueue/LinkedBlockingQueue以FIFO(先进先出)的顺序在内部存储元素。队列的头部是在队列中停留时间最长的元素,而队列的尾部是在队列中停留时间最短的元素。
区别
LinkedBlockingQueue实现使用的是“双锁队列”算法。因此,LinkedBlockingQueue的take和put可以并发工作,但ArrayBlockingQueue不行。使用单锁的原因在于ArrayBlockingQueue需要避免覆盖条目,因此需要知道开始和结束位置。LinkedBlockQueue不需要这样做,因为它让GC(垃圾回收机制)负责清理队列中的节点。
ArrayBlockingQueue<E>
和LinkedBlockingQueue<E>
是BlockingQueue<E>
接口的常见实现。
ArrayBlockingQueue
由数组
支持,Queue
强制按照FIFO
排序。队列头是最老的元素,队列尾是最年轻的元素。ArrayBlockingQueue
是一个大小固定的有界缓冲区,而LinkedBlockingQueue
是一个基于链表节点的可选有界队列。
可选的容量绑定构造函数参数可以防止过度扩展队列,因为如果未指定容量,则等于Integer.MAX_VALUE
。
更多信息请查看这里。
基准测试:http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html