- 类型参数:
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 元素。实现抛出 NullPointerException 尝试 add , put 或 offer a null 。 null 用作标记值以指示 poll 操作失败。
BlockingQueue 可能是有容量限制的。在任何给定时间,它都可能有一个remainingCapacity,超过它就没有其他元素可以put而不阻塞。没有任何内在容量限制的 BlockingQueue 始终报告 Integer.MAX_VALUE 的剩余容量。
BlockingQueue 实现主要用于生产者-消费者队列,但还支持 Collection 接口。因此,例如,可以使用 remove(x) 从队列中删除任意元素。但是,此类操作通常not执行得非常高效,并且仅供偶尔使用,例如取消排队的消息时。
BlockingQueue 实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。然而,bulk 集合操作addAll、containsAll、retainAll 和removeAll 必须以原子方式执行,除非在实现中另有说明。因此,例如,在仅添加 c 中的一些元素后, addAll(c) 可能会失败(抛出异常)。
BlockingQueue 确实 not 本质上支持任何类型的“关闭”或“关闭”操作以指示不再添加任何项目。此类功能的需求和使用往往取决于实现。例如,一种常见的策略是生产者插入特殊的 end-of-stream 或 poison 对象,这些对象在消费者获取时会进行相应的解释。
使用示例,基于典型的生产者-消费者场景。请注意,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) { ... handle ...}
}
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) { ... handle ...}
}
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 发生在之前 之前线程中的操作是在另一个线程中从 BlockingQueue 访问或删除该元素之后的操作。
此接口是 Java 集合框架 的成员。
- 自从:
- 1.5
-
方法总结
修饰符和类型方法描述boolean如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回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()检索并删除此队列的头部,必要时等待直到元素可用。在接口 java.util.Collection 中声明的方法
addAll, clear, containsAll, equals, hashCode, isEmpty, iterator, parallelStream, removeAll, removeIf, retainAll, size, spliterator, stream, toArray, toArray, toArray
-
方法详情
-
add
如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回true并在当前没有可用空间时抛出IllegalStateException。使用容量受限队列时,通常最好使用offer。- 指定者:
add在接口Collection<E>中- 指定者:
add在接口Queue<E>中- 参数:
e- 要添加的元素- 返回:
true(由Collection.add(E)指定)- 抛出:
IllegalStateException- 如果由于容量限制此时无法添加元素ClassCastException- 如果指定元素的类阻止它被添加到这个队列NullPointerException- 如果指定元素为空IllegalArgumentException- 如果指定元素的某些属性阻止它被添加到这个队列
-
offer
如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回true,如果当前没有可用空间则返回false。当使用容量受限队列时,此方法通常优于add(E),后者仅通过抛出异常才能插入元素失败。- 指定者:
offer在接口Queue<E>中- 参数:
e- 要添加的元素- 返回:
true如果元素被添加到这个队列,否则false- 抛出:
ClassCastException- 如果指定元素的类阻止它被添加到这个队列NullPointerException- 如果指定元素为空IllegalArgumentException- 如果指定元素的某些属性阻止它被添加到这个队列
-
put
将指定元素插入此队列,必要时等待可用空间。- 参数:
e- 要添加的元素- 抛出:
InterruptedException- 如果在等待时被打断ClassCastException- 如果指定元素的类阻止它被添加到这个队列NullPointerException- 如果指定元素为空IllegalArgumentException- 如果指定元素的某些属性阻止它被添加到这个队列
-
offer
将指定的元素插入此队列,如有必要,等待指定的等待时间以获得可用空间。- 参数:
e- 要添加的元素timeout- 放弃前等待多长时间,以unit为单位unit- 一个TimeUnit决定如何解释timeout参数- 返回:
true如果成功,或者false如果指定的等待时间在空间可用之前过去- 抛出:
InterruptedException- 如果在等待时被打断ClassCastException- 如果指定元素的类阻止它被添加到这个队列NullPointerException- 如果指定元素为空IllegalArgumentException- 如果指定元素的某些属性阻止它被添加到这个队列
-
take
检索并删除此队列的头部,必要时等待直到元素可用。- 返回:
- 这个队列的头
- 抛出:
InterruptedException- 如果在等待时被打断
-
poll
检索并删除此队列的头部,如有必要,等待指定的等待时间以使元素可用。- 参数:
timeout- 放弃前等待多长时间,以unit为单位unit- 一个TimeUnit决定如何解释timeout参数- 返回:
-
此队列的头部,或者
null如果指定的等待时间在元素可用之前过去 - 抛出:
InterruptedException- 如果在等待时被打断
-
remainingCapacity
int remainingCapacity()返回此队列可以理想地(在没有内存或资源限制的情况下)无阻塞地接受的附加元素的数量,如果没有内在限制,则返回Integer.MAX_VALUE。请注意,您 cannot 总是通过检查
remainingCapacity来判断插入元素的尝试是否会成功,因为可能是另一个线程即将插入或删除元素的情况。- 返回:
- 剩余容量
-
remove
从此队列中移除指定元素的单个实例(如果存在)。更正式地说,如果此队列包含一个或多个此类元素,则删除一个元素e使得o.equals(e)。如果此队列包含指定元素,则返回true(或者等效地,如果此队列因调用而更改)。- 指定者:
remove在接口Collection<E>中- 参数:
o- 要从此队列中删除的元素(如果存在)- 返回:
true如果此队列因调用而更改- 抛出:
ClassCastException- 如果指定元素的类与此队列不兼容 (optional)NullPointerException- 如果指定元素为空 (optional)
-
contains
如果此队列包含指定元素,则返回true。更正式地说,返回true当且仅当此队列包含至少一个元素e使得o.equals(e)。- 指定者:
contains在接口Collection<E>中- 参数:
o- 要检查此队列中包含的对象- 返回:
true如果此队列包含指定元素- 抛出:
ClassCastException- 如果指定元素的类与此队列不兼容 (optional)NullPointerException- 如果指定元素为空 (optional)
-
drainTo
从此队列中删除所有可用元素并将它们添加到给定集合中。此操作可能比重复轮询此队列更有效。尝试将元素添加到集合c时遇到的失败可能会导致在抛出相关异常时元素不在任何一个或两个集合中。尝试将队列排空到自身会导致IllegalArgumentException。此外,如果指定的集合在操作过程中被修改,则此操作的行为是未定义的。- 参数:
c- 将元素转移到的集合- 返回:
- 转移的元素数量
- 抛出:
UnsupportedOperationException- 如果指定集合不支持添加元素ClassCastException- 如果此队列元素的类阻止将其添加到指定集合NullPointerException- 如果指定的集合为空IllegalArgumentException- 如果指定的集合是这个队列,或者这个队列元素的某些属性阻止它被添加到指定的集合
-
drainTo
从此队列中最多移除给定数量的可用元素,并将它们添加到给定的集合中。尝试将元素添加到集合c时遇到的失败可能会导致在抛出相关异常时元素不在任何一个或两个集合中。尝试将队列排空到自身会导致IllegalArgumentException。此外,如果指定的集合在操作过程中被修改,则此操作的行为是未定义的。- 参数:
c- 将元素转移到的集合maxElements- 要传输的最大元素数- 返回:
- 转移的元素数量
- 抛出:
UnsupportedOperationException- 如果指定集合不支持添加元素ClassCastException- 如果此队列元素的类阻止将其添加到指定集合NullPointerException- 如果指定的集合为空IllegalArgumentException- 如果指定的集合是这个队列,或者这个队列元素的某些属性阻止它被添加到指定的集合
-