模块 java.base

接口 BlockingQueue<E>

类型参数:
E - 此队列中保存的元素类型
所有父级接口:
Collection<E> , Iterable<E> , Queue<E>
所有已知的子接口:
BlockingDeque<E> , TransferQueue<E>
所有已知的实现类:
ArrayBlockingQueue , DelayQueue , LinkedBlockingDeque , LinkedBlockingQueue , LinkedTransferQueue , PriorityBlockingQueue , SynchronousQueue

public interface BlockingQueue<E> extends Queue <E>
Queue 还支持在检索元素时等待队列变为非空的操作,并在存储元素时等待队列中的空间可用。

BlockingQueue 方法有四种形式,以不同的方式处理不能立即满足但可能在将来某个时间点满足的操作:一种抛出异常,第二种返回一个特殊值(nullfalse,取决于操作),第三个无限期地阻塞当前线程,直到操作成功,第四个在放弃之前只阻塞给定的最大时间限制。下表总结了这些方法:

BlockingQueue 方法总结
抛出异常 特殊值 积木 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
消除 remove() poll() take() poll(time, unit)
检查 element() peek() 不适用 不适用

BlockingQueue 不接受 null 元素。实现抛出 NullPointerException 尝试 addputoffer a nullnull 用作标记值以指示 poll 操作失败。

BlockingQueue 可能是有容量限制的。在任何给定时间,它都可能有一个remainingCapacity,超过它就没有其他元素可以put而不阻塞。没有任何内在容量限制的 BlockingQueue 始终报告 Integer.MAX_VALUE 的剩余容量。

BlockingQueue 实现主要用于生产者-消费者队列,但还支持 Collection 接口。因此,例如,可以使用 remove(x) 从队列中删除任意元素。但是,此类操作通常not执行得非常高效,并且仅供偶尔使用,例如取消排队的消息时。

BlockingQueue 实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。然而,bulk 集合操作addAllcontainsAllretainAllremoveAll 必须以原子方式执行,除非在实现中另有说明。因此,例如,在仅添加 c 中的一些元素后, addAll(c) 可能会失败(抛出异常)。

BlockingQueue 确实 not 本质上支持任何类型的“关闭”或“关闭”操作以指示不再添加任何项目。此类功能的需求和使用往往取决于实现。例如,一种常见的策略是生产者插入特殊的 end-of-streampoison 对象,这些对象在消费者获取时会进行相应的解释。

使用示例,基于典型的生产者-消费者场景。请注意,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
    add(E e)
    如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回 true 并在当前没有可用空间时抛出 IllegalStateException
    boolean
    如果此队列包含指定元素,则返回 true
    int
    drainTo(Collection<? super E> c)
    从此队列中删除所有可用元素并将它们添加到给定集合中。
    int
    drainTo(Collection<? super E> c, int maxElements)
    从此队列中最多移除给定数量的可用元素,并将它们添加到给定的集合中。
    boolean
    offer(E e)
    如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回 true,如果当前没有可用空间则返回 false
    boolean
    offer(E e, long timeout, TimeUnit unit)
    将指定的元素插入此队列,如有必要,等待指定的等待时间以获得可用空间。
    E
    poll(long timeout, TimeUnit unit)
    检索并删除此队列的头部,如有必要,等待指定的等待时间以使元素可用。
    void
    put(E e)
    将指定元素插入此队列,必要时等待可用空间。
    int
    返回此队列可以理想地(在没有内存或资源限制的情况下)无阻塞地接受的附加元素的数量,如果没有内在限制,则返回 Integer.MAX_VALUE
    boolean
    从此队列中移除指定元素的单个实例(如果存在)。
    E
    take()
    检索并删除此队列的头部,必要时等待直到元素可用。

    在接口 java.lang.Iterable 中声明的方法

    forEach

    在接口 java.util.Queue 中声明的方法

    element, peek, poll, remove
  • 方法详情

    • add

      boolean add(E  e)
      如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回 true 并在当前没有可用空间时抛出 IllegalStateException。使用容量受限队列时,通常最好使用 offer
      指定者:
      add 在接口 Collection<E>
      指定者:
      add 在接口 Queue<E>
      参数:
      e - 要添加的元素
      返回:
      true(由 Collection.add(E) 指定)
      抛出:
      IllegalStateException - 如果由于容量限制此时无法添加元素
      ClassCastException - 如果指定元素的类阻止它被添加到这个队列
      NullPointerException - 如果指定元素为空
      IllegalArgumentException - 如果指定元素的某些属性阻止它被添加到这个队列
    • offer

      boolean offer(E  e)
      如果可以在不违反容量限制的情况下立即将指定的元素插入此队列,则在成功时返回 true,如果当前没有可用空间则返回 false。当使用容量受限队列时,此方法通常优于 add(E) ,后者仅通过抛出异常才能插入元素失败。
      指定者:
      offer 在接口 Queue<E>
      参数:
      e - 要添加的元素
      返回:
      true 如果元素被添加到这个队列,否则 false
      抛出:
      ClassCastException - 如果指定元素的类阻止它被添加到这个队列
      NullPointerException - 如果指定元素为空
      IllegalArgumentException - 如果指定元素的某些属性阻止它被添加到这个队列
    • put

      void put(E  e) throws InterruptedException
      将指定元素插入此队列,必要时等待可用空间。
      参数:
      e - 要添加的元素
      抛出:
      InterruptedException - 如果在等待时被打断
      ClassCastException - 如果指定元素的类阻止它被添加到这个队列
      NullPointerException - 如果指定元素为空
      IllegalArgumentException - 如果指定元素的某些属性阻止它被添加到这个队列
    • offer

      boolean offer(E  e, long timeout, TimeUnit  unit) throws InterruptedException
      将指定的元素插入此队列,如有必要,等待指定的等待时间以获得可用空间。
      参数:
      e - 要添加的元素
      timeout - 放弃前等待多长时间,以 unit 为单位
      unit - 一个 TimeUnit 决定如何解释 timeout 参数
      返回:
      true 如果成功,或者 false 如果指定的等待时间在空间可用之前过去
      抛出:
      InterruptedException - 如果在等待时被打断
      ClassCastException - 如果指定元素的类阻止它被添加到这个队列
      NullPointerException - 如果指定元素为空
      IllegalArgumentException - 如果指定元素的某些属性阻止它被添加到这个队列
    • take

      E  take() throws InterruptedException
      检索并删除此队列的头部,必要时等待直到元素可用。
      返回:
      这个队列的头
      抛出:
      InterruptedException - 如果在等待时被打断
    • poll

      E  poll(long timeout, TimeUnit  unit) throws InterruptedException
      检索并删除此队列的头部,如有必要,等待指定的等待时间以使元素可用。
      参数:
      timeout - 放弃前等待多长时间,以 unit 为单位
      unit - 一个 TimeUnit 决定如何解释 timeout 参数
      返回:
      此队列的头部,或者 null 如果指定的等待时间在元素可用之前过去
      抛出:
      InterruptedException - 如果在等待时被打断
    • remainingCapacity

      int remainingCapacity()
      返回此队列可以理想地(在没有内存或资源限制的情况下)无阻塞地接受的附加元素的数量,如果没有内在限制,则返回 Integer.MAX_VALUE

      请注意,您 cannot 总是通过检查 remainingCapacity 来判断插入元素的尝试是否会成功,因为可能是另一个线程即将插入或删除元素的情况。

      返回:
      剩余容量
    • remove

      boolean remove(Object  o)
      从此队列中移除指定元素的单个实例(如果存在)。更正式地说,如果此队列包含一个或多个此类元素,则删除一个元素 e 使得 o.equals(e) 。如果此队列包含指定元素,则返回 true(或者等效地,如果此队列因调用而更改)。
      指定者:
      remove 在接口 Collection<E>
      参数:
      o - 要从此队列中删除的元素(如果存在)
      返回:
      true 如果此队列因调用而更改
      抛出:
      ClassCastException - 如果指定元素的类与此队列不兼容 (optional)
      NullPointerException - 如果指定元素为空 (optional)
    • contains

      boolean contains(Object  o)
      如果此队列包含指定元素,则返回 true。更正式地说,返回 true 当且仅当此队列包含至少一个元素 e 使得 o.equals(e)
      指定者:
      contains 在接口 Collection<E>
      参数:
      o - 要检查此队列中包含的对象
      返回:
      true 如果此队列包含指定元素
      抛出:
      ClassCastException - 如果指定元素的类与此队列不兼容 (optional)
      NullPointerException - 如果指定元素为空 (optional)
    • drainTo

      int drainTo(Collection <? super E > c)
      从此队列中删除所有可用元素并将它们添加到给定集合中。此操作可能比重复轮询此队列更有效。尝试将元素添加到集合 c 时遇到的失败可能会导致在抛出相关异常时元素不在任何一个或两个集合中。尝试将队列排空到自身会导致 IllegalArgumentException 。此外,如果指定的集合在操作过程中被修改,则此操作的行为是未定义的。
      参数:
      c - 将元素转移到的集合
      返回:
      转移的元素数量
      抛出:
      UnsupportedOperationException - 如果指定集合不支持添加元素
      ClassCastException - 如果此队列元素的类阻止将其添加到指定集合
      NullPointerException - 如果指定的集合为空
      IllegalArgumentException - 如果指定的集合是这个队列,或者这个队列元素的某些属性阻止它被添加到指定的集合
    • drainTo

      int drainTo(Collection <? super E > c, int maxElements)
      从此队列中最多移除给定数量的可用元素,并将它们添加到给定的集合中。尝试将元素添加到集合 c 时遇到的失败可能会导致在抛出相关异常时元素不在任何一个或两个集合中。尝试将队列排空到自身会导致 IllegalArgumentException 。此外,如果指定的集合在操作过程中被修改,则此操作的行为是未定义的。
      参数:
      c - 将元素转移到的集合
      maxElements - 要传输的最大元素数
      返回:
      转移的元素数量
      抛出:
      UnsupportedOperationException - 如果指定集合不支持添加元素
      ClassCastException - 如果此队列元素的类阻止将其添加到指定集合
      NullPointerException - 如果指定的集合为空
      IllegalArgumentException - 如果指定的集合是这个队列,或者这个队列元素的某些属性阻止它被添加到指定的集合