43
  1. 什么情况下使用 ArrayBlockingQueue 更好,什么时候使用 LinkedBlockingQueue 更好?
  2. 如果 LinkedBlockingQueue 默认容量等于 MAX Integer,那么将其用作具有默认容量的 BlockingQueue 真的有帮助吗?
4

4 回答 4

26

ArrayBlockingQueue由一个数组支持,该数组的大小在创建后永远不会改变。将容量设置为Integer.MAX_VALUE将创建一个空间成本高的大阵列。 ArrayBlockingQueue总是有界的。

LinkedBlockingQueue动态创建节点,直到capacity达到。这是默认设置Integer.MAX_VALUE。使用如此大的容量并没有额外的空间成本。 LinkedBlockingQueue是可选有界的。

于 2013-08-22T08:46:24.850 回答
16

ArrayBlockingQueue<E>并且LinkedBlockingQueue<E>BlockingQueue<E>接口的常见实现。

ArrayBlockingQueue由 支持arrayQueue下达命令FIFO。就时间而言,队列的头部是最老的元素,队列的尾部是最年轻的元素。ArrayBlockingQueue另一方面,它也是固定大小的有界缓冲区,LinkedBlockingQueue是建立在链接节点之上的可选有界队列。

可选的容量绑定构造函数参数用作防止过度队列扩展的一种方式,因为如果未指定容量,则它等于Integer.MAX_VALUE.

从这里阅读更多信息。

基准测试:http ://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html

于 2013-08-22T09:00:44.987 回答
16

数组阻塞队列

ArrayBlockingQueue 是一个有界的阻塞队列,它将元素内部存储在一个数组中。它是有界的意味着它不能存储无限数量的元素。它可以同时存储的元素数量有一个上限。您在实例化时设置上限,之后就无法更改。

链接阻塞队列

LinkedBlockingQueue 将元素内部保持在链接结构(链接节点)中。如果需要,此链接结构可以选择具有上限。如果没有指定上限,则使用 Integer.MAX_VALUE 作为上限。

相似

ArrayBlockingQueue/LinkedBlockingQueue 以 FIFO(先进先出)的顺序在内部存储元素。队列头是入队时间最长的元素,队列尾是入队时间最短的元素。

差异

  • LinkedBlockingQueue 有一个 putLock 和一个 takeLock 分别用于插入和删除,但 ArrayBlockingQueue 只使用 1 个锁。
  • ArrayBlockingQueue 使用单锁双条件算法,LinkedBlockingQueue 是“双锁队列”算法的变体,它有 2 个锁 2 个条件(takeLock,putLock)。

LinkedBlockingQueue 实现使用了两个锁队列算法。因此 LinkedBlockingQueue 的 take 和 put 可以同时工作,但 ArrayBlockingQueue 不是这种情况。在 ArrayBlockingQueue 中使用单个锁的原因是,ArrayBlockingQueue 必须避免覆盖条目,以便它需要知道开始和结束的位置。LinkedBlockQueue 不需要知道这一点,因为它让 GC 担心清理队列中的节点。

于 2018-01-06T18:32:12.360 回答
8

向 ArrayBlockingQueue 添加元素应该更快,因为这意味着只设置对支持 Object 数组的元素的引用,而向 LinkedBlockingQueue 添加元素意味着创建一个节点并设置它的 item、prev 和 next 字段。此外,当我们从 LinkedBlockingQueue 中删除一个元素时,删除的节点会变成垃圾,这可能会影响应用程序的性能。

至于内存消耗 ArrayBlockingQueue 总是保存一个满容量的 Object 数组,即使是空的。另一方面,LinkedBlockingQueue 中的一个元素是一个具有 3 个对象字段的对象的节点。

于 2013-08-22T09:17:24.650 回答