BlockingQueue译为阻塞队列 ,它是JDK 1.5添加的新的工具类,它继承于Queue队列,并扩展了Queue的功能。

BlockingQueue在检索元素时会等待队列变成非空,并在存储元素时会等待队列变为可用。
BlockingQueue的方法有四种实现形式,以不同的方式来处理。

  • 第一种是抛出异常
  • 特殊值:第二种是根据情况会返回null或者false
  • 阻塞:第三种是无限期的阻塞当前线程直到操作变为可用后
  • 超时:第四种是给定一个最大的超时时间,超过后才会放弃

BlockingQueue不允许添加null元素,在其实现类的方法add、put 或者offer后时添加null 会抛出空指针异常。BlockingQueue 会有容量限制。在任意时间内,它都会有一个remainCapacity,超过该值之前,任意put元素都会阻塞。

BlockingQueue 一般用于实现生产者一消费者队列,如下图所示
image.png

实现代码

  1. package com.lxd;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. public class BlockingQueueDemo {
  4. static ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(2);
  5. public static void main(String[] args) {
  6. // 生产者
  7. for (int i = 0; i < 3; i++) {
  8. new Thread(() -> producer(), "producerThread" + i).start();
  9. }
  10. // 消费者
  11. for (int i = 0; i < 3; i++) {
  12. new Thread(() -> consumer(), "consumerThread" + i).start();
  13. }
  14. }
  15. private static void consumer() {
  16. while (true) {
  17. try {
  18. String msg = abq.take();
  19. System.out.println(Thread.currentThread().getName() + " ->receive msg:" + msg);
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25. private static void producer() {
  26. for (int i = 0; i < 100; i++) {
  27. try {
  28. abq.put("[" + i + "]");
  29. System.out.println(Thread.currentThread().getName() + " ->send msg:" + i);
  30. } catch (InterruptedException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  35. }

BlockingQueue有多种实现,其中LinkedBlockingQueue 和ArrayBlockingQueue 是FIFO先入先出队列,二者分别和LinkedList和ArrayList 对应,比同步List具有更好的并发性能。PriorityBlockingQueue是一个优先级排序的阻塞队列,如果你希望按照某种顺序而不是FIFO处理元素时这个队列将非常有用。正如其他有序的容器一样, PriorityBlockingQueue 既可以按照自然顺序来比较元素,也可以使用Comparator比较器进行外部元素比较。SynchronousQueue 它维护的是一 组线程而不是一 组队列,实际上它不是一个队列,它的每个insert 操作必须等待其他相关线程的remove方法后才能执行,反之亦然。

LinkedBlockingQueue

它是一种基于链表的构造、先入先出的有界阻塞队列。队列的head 也就是头元素是 在队列中等待时间最长的元素;队列的tail 也就是队尾元素是队列中等待时间最短的元素。新的元素会被插入到队尾中,检索操作将获取队列中的头部元素。链表队列通常比基于数组的队列具有更高的吞吐量;但是在大多数并发应用程序中,可预测的性能较差。

ArrayBlockingQueue

ArrayBlockingQueue是一个用数组实现的有界队列,此队列顺序按照先入先出的原则对元素进行排序。默认情况下不保证线程公平的访问队列,所谓公平访问队列指的是阻塞的线程,可以按照阻塞的先后顺序访问,即先阻塞线程先访问队列。非公平性是对先等待的线程是非公平的。有可能先阻塞的线程最后才访问队列。

PriorityBlockingQueue

PriorityBlockingQueue是一 个支持优先级的阻塞队列,默认情况下的元素采取自然顺序生序或者降序,也可以自己定义Comparator进行外部排序。但需要注意的是不能保证同优先级元素的顺序。