- 类型参数:
-
E- 此队列中保存的元素的类型
- 所有超接口:
-
Collection<E>,Iterable<E>,Queue<E>
- 所有已知子接口:
-
BlockingDeque<E>,TransferQueue<E>
- 所有已知实现类:
-
ArrayBlockingQueue,DelayQueue,LinkedBlockingDeque,LinkedBlockingQueue,LinkedTransferQueue,PriorityBlockingQueue,SynchronousQueue
Queue,除了支持等待队列在检索元素时变得非空,还支持等待队列在存储元素时有空间可用。
BlockingQueue方法有四种形式,处理无法立即满足的操作,但可能在将来某个时刻满足:一种会抛出异常,第二种返回特殊值(null或false,取决于操作),第三种无限期地阻塞当前线程,直到操作成功,第四种在放弃之前仅阻塞一定的最大时间限制。这些方法在下表中总结如下:
| 抛出异常 | 特殊值 | 阻塞 | 超时 | |
|---|---|---|---|---|
| 插入 | add(e) |
offer(e) |
put(e) |
offer(e, time, unit) |
| 移除 | remove() |
poll() |
take() |
poll(time, unit) |
| 检查 | element() |
peek() |
不适用 | 不适用 |
BlockingQueue不接受null元素。如果尝试向队列中add、put或offer一个null元素,实现会抛出NullPointerException。null被用作一个特殊值,表示poll操作失败。
BlockingQueue可能具有容量限制。在任何给定时间,它可能具有remainingCapacity,超过该容量,不能再put额外的元素而不阻塞。没有任何固有容量约束的BlockingQueue总是报告Integer.MAX_VALUE的剩余容量。
BlockingQueue实现主要用于生产者-消费者队列,但还支持Collection接口。因此,例如,可以使用remove(x)从队列中删除任意元素。但是,这些操作通常不会非常高效,并且仅用于偶尔使用,例如在取消排队消息时。
BlockingQueue实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现它们的效果。但是,批量Collection操作addAll、containsAll、retainAll和removeAll除非在实现中另有规定,否则不一定是原子操作。因此,例如,addAll(c)可能在仅添加c中的一些元素后失败(抛出异常)。
BlockingQueue不会本质上支持任何类型的“关闭”或“关闭”操作,以指示不会再添加更多项目。这些功能的需求和使用往往依赖于实现。例如,一个常见的策略是生产者插入特殊的“流结束”或“毒药”对象,当消费者取走时会相应地解释。
基于典型的生产者-消费者场景的使用示例。请注意,BlockingQueue可以安全地与多个生产者和多个消费者一起使用。
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... 处理 ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... 处理 ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
内存一致性效果: 与其他并发集合一样,一个线程在将对象放入BlockingQueue之前的操作在另一个线程中访问或移除该元素之后的操作之前发生。
此接口是Java集合框架的成员。
- 自 JDK 版本:
- 1.5
-
Method Summary
Modifier and TypeMethodDescriptionboolean如果可以立即这样做而不违反容量限制,则将指定的元素插入此队列,成功时返回true,如果当前没有空间,则抛出IllegalStateException。boolean如果此队列包含指定的元素,则返回true。intdrainTo(Collection<? super E> c) 从此队列中删除所有可用元素并将它们添加到给定的集合中。intdrainTo(Collection<? super E> c, int maxElements) 从此队列中最多删除给定数量的可用元素,并将它们添加到给定的集合中。boolean如果可以立即这样做而不违反容量限制,则将指定的元素插入此队列,成功时返回true,如果当前没有空间,则返回false。boolean如果需要,将指定的元素插入此队列,并等待指定的等待时间,直到有空间可用。检索并移除此队列的头部,在必要时等待指定的等待时间,直到有元素可用。void如果需要,将指定的元素插入此队列,并等待直到有空间可用。int返回此队列可以理想地(在没有内存或资源约束的情况下)接受的附加元素数量,如果没有固有限制,则返回Integer.MAX_VALUE。boolean从此队列中删除指定元素的单个实例(如果存在)。take()检索并移除此队列的头部,在必要时等待直到有元素可用。Methods declared in interface java.util.Collection
addAll, clear, containsAll, equals, hashCode, isEmpty, iterator, parallelStream, removeAll, removeIf, retainAll, size, spliterator, stream, toArray, toArray, toArray
-
Method Details
-
add
- 指定者:
-
add在接口Collection<E>中 - 指定者:
-
add在接口Queue<E>中 - 参数:
-
e- 要添加的元素 - 返回:
-
true(由Collection.add(E)指定) - 抛出:
-
IllegalStateException- 如果由于容量限制而此时无法添加元素 -
ClassCastException- 如果指定元素的类阻止将其添加到此队列中 -
NullPointerException- 如果指定元素为null -
IllegalArgumentException- 如果指定元素的某些属性阻止将其添加到此队列中
-
offer
将指定的元素立即插入此队列(如果可以在不违反容量限制的情况下进行),成功时返回true,如果当前没有可用空间则返回false。在使用容量受限队列时,通常应优先使用此方法,而不是add(E),因为后者可能仅通过抛出异常来阻止插入元素。- 指定者:
-
offer在接口Queue<E> - 参数:
-
e- 要添加的元素 - 返回:
-
如果元素已添加到此队列,则返回
true,否则返回false - 抛出:
-
ClassCastException- 如果指定元素的类别阻止将其添加到此队列 -
NullPointerException- 如果指定元素为null -
IllegalArgumentException- 如果指定元素的某些属性阻止将其添加到此队列
-
put
将指定的元素插入此队列,必要时等待空间变得可用。- 参数:
-
e- 要添加的元素 - 抛出:
-
InterruptedException- 在等待时被中断 -
ClassCastException- 如果指定元素的类别阻止将其添加到此队列 -
NullPointerException- 如果指定元素为null -
IllegalArgumentException- 如果指定元素的某些属性阻止将其添加到此队列
-
offer
将指定的元素插入此队列,必要时等待指定的等待时间以使空间变得可用。- 参数:
-
e- 要添加的元素 -
timeout- 等待放弃之前的时间长度,以unit为单位 -
unit- 一个TimeUnit,用于解释timeout参数 - 返回:
-
如果成功,则返回
true,如果指定的等待时间在空间可用之前过去,则返回false - 抛出:
-
InterruptedException- 在等待时被中断 -
ClassCastException- 如果指定元素的类别阻止将其添加到此队列 -
NullPointerException- 如果指定元素为null -
IllegalArgumentException- 如果指定元素的某些属性阻止将其添加到此队列
-
take
检索并移除此队列的头部,必要时等待直到有元素可用。- 返回:
- 此队列的头部
- 抛出:
-
InterruptedException- 在等待时被中断
-
poll
检索并移除此队列的头部,必要时等待指定的等待时间以使元素可用。- 参数:
-
timeout- 等待放弃之前的时间长度,以unit为单位 -
unit- 一个TimeUnit,用于解释timeout参数 - 返回:
-
此队列的头部,如果指定的等待时间在元素可用之前过去,则返回
null - 抛出:
-
InterruptedException- 在等待时被中断
-
remainingCapacity
int remainingCapacity()返回此队列理想情况下(在没有内存或资源限制的情况下)可以接受的附加元素数量,如果没有固有限制,则返回Integer.MAX_VALUE。请注意,您不能仅通过检查
remainingCapacity来始终确定插入元素的尝试是否成功,因为可能会出现另一个线程即将插入或移除元素的情况。- 返回:
- 剩余容量
-
remove
从此队列中删除指定元素的单个实例(如果存在)。更正式地说,删除一个元素e,使得o.equals(e),如果此队列包含一个或多个这样的元素,则返回true(或等效地,如果此队列由于调用而更改,则返回true)。- 指定者:
-
remove在接口Collection<E> - 参数:
-
o- 如果存在,则从此队列中删除的元素 - 返回:
-
如果此队列由于调用而更改,则返回
true - 抛出:
-
ClassCastException- 如果指定元素的类别与此队列不兼容(可选) -
NullPointerException- 如果指定元素为null(可选)
-
contains
如果此队列包含指定元素,则返回true。更正式地说,如果此队列包含至少一个元素e,使得o.equals(e),则返回true。- 指定者:
-
contains在接口Collection<E> - 参数:
-
o- 要在此队列中检查包含性的对象 - 返回:
-
如果此队列包含指定元素,则返回
true - 抛出:
-
ClassCastException- 如果指定元素的类别与此队列不兼容(可选) -
NullPointerException- 如果指定元素为null(可选)
-
drainTo
从此队列中移除所有可用元素并将它们添加到给定的集合中。此操作可能比重复轮询此队列更有效。在尝试将元素添加到集合c时遇到失败可能导致在抛出相关异常时元素既不在集合c中,也不在此队列中,或者同时在两个集合中。尝试将队列排空到自身会导致IllegalArgumentException。此外,如果在操作进行中修改了指定的集合,则此操作的行为是未定义的。- 参数:
-
c- 要将元素传输到其中的集合 - 返回:
- 传输的元素数量
- 抛出:
-
UnsupportedOperationException- 如果指定集合不支持添加元素 -
ClassCastException- 如果此队列的元素类别阻止将其添加到指定集合 -
NullPointerException- 如果指定集合为null -
IllegalArgumentException- 如果指定集合为此队列,或者此队列的某个元素属性阻止将其添加到指定集合
-
drainTo
从此队列中最多移除给定数量的可用元素并将它们添加到给定的集合中。在尝试将元素添加到集合c时遇到失败可能导致在抛出相关异常时元素既不在集合c中,也不在此队列中,或者同时在两个集合中。尝试将队列排空到自身会导致IllegalArgumentException。此外,如果在操作进行中修改了指定的集合,则此操作的行为是未定义的。- 参数:
-
c- 要传输元素的集合 -
maxElements- 要传输的最大元素数量 - 返回值:
- 传输的元素数量
- 抛出:
-
UnsupportedOperationException- 如果指定集合不支持添加元素 -
ClassCastException- 如果此队列的元素类别阻止将其添加到指定集合中 -
NullPointerException- 如果指定集合为null -
IllegalArgumentException- 如果指定集合为此队列,或者此队列的某个元素属性阻止将其添加到指定集合中
-