JavaSE 中的队列简介

一、Java 中的队列

Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构。

Queue 接口与 List、Set同一级别,都是继承了Collection接口。

队列分为两大类:非阻塞队列和阻塞队列

image-20210825085547395

二、非阻塞队列

非阻塞队列不能阻塞,多线程时,当队列满或者队列空时,只能使用队列 wait(),notify() 进行队列消息传送。

1. LinkedList(基于链表的FIFO队列)

LinkedList 除了实现的 List 接口,也实现了 Deque 接口,可以当做双端队列来使用。

2. ArrayDeque(数组双端队列)

ArrayDequeDeque接口的一个实现,使用了可变数组,所以没有容量上的限制。同时,ArrayDeque是线程不安全的,在没有外部同步的情况下,不能在多线程环境下使用。

ArrayDequeDeque的实现类,可以作为栈来使用,效率高于Stack;也可以作为队列来使用,效率高于LinkedList。需要注意的是,ArrayDeque不支持null值。

3. PriorityQueue(优先级队列)

PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。该队列不允许使用 null 元素也不允许插入不可比较的对象

PriorityQueue 队列的头指排序规则最小那个元素。如果多个元素都是最小值则随机选一个。
PriorityQueue 是一个无界队列,但是初始的容量(实际是一个Object[]),随着不断向优先级队列添加元素,其容量会自动扩容,无需指定容量增加策略的细节。

4. ConcurrentLinkedQueue(基于链表的并发队列)

ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列(CAS)。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小,ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。

同样此队列不允许使用null元素,

非阻塞队列的操作方法
  • add(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则会抛出异常;

  • remove():移除队首元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常;

  • remove(Object o):移除指定的元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常

  • offer(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则返回 false;

  • poll():移除并获取队首元素,若成功,则返回队首元素;否则返回 null;

  • peek():获取队首元素,若成功,则返回队首元素;否则返回 null

  • isEmpty():队列是否为空

  • size():队列长度

对于非阻塞队列,一般情况下建议使用 offer、poll 和 peek 三个方法,不建议使用 add 和 remove 方法。因为使用 offer、poll 和 peek 三个方法可以通过返回值判断操作成功与否,而使用 add 和 remove 方法却不能达到这样的效果。

注意:非阻塞队列中的方法都没有进行同步措施。

三、阻塞队列

阻塞队列可以阻塞,当阻塞队列当队列里面没有值时,会阻塞直到有值输入。输入也一样,当队列满的时候,会阻塞,直到队列有空间。

1. 阻塞队列
  • ArrayBlockingQueue :一个由数组支持的有界队列。(基于数组的并发阻塞队列)
  • LinkedBlockingQueue :一个由链接节点支持的可选有界队列。(基于链表的FIFO阻塞队列)
  • PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。(带优先级的无界阻塞队列)
  • DelayQueue :一个由优先级堆支持的、基于时间的调度队列。(延期阻塞队列)
  • SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。
  • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
  • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
2. 阻塞队列的操作方法

阻塞队列包括了非阻塞队列中的大部分方法,上面列举的5个方法在阻塞队列中都存在,但是要注意这5个方法在阻塞队列中都进行了同步措施。

除此之外,阻塞队列提供了另外4个非常有用的方法:

  • put(E e):用来向队尾存入元素,如果队列满,则等待;
  • take():用来从队首取元素,如果队列为空,则等待;
  • offer(E e,long timeout, TimeUnit unit):用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;
  • poll(long timeout, TimeUnit unit):用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回null;否则返回取得的元素;
posted @ 2021-08-25 09:19  Binge-和时间做朋友  阅读(59)  评论(0编辑  收藏  举报