数据结构-队列篇

队列是程序中十分重要的一种数据结构,这篇文章就对Java中的队列进行梳理介绍。该篇文章主要从队列的概念入手,后续再从源码角度刨析写一篇文章。

一、定义

(1)特性:先进先出(FIFO)
(2)底层结构:数组+链表

二、关系图

在这里插入图片描述

三、分类

1、阻塞队列

(1)ArrayBlockingQueue有界队列
  ArrayBlockingQueue是用数组实现的有界阻塞队列。这种队列中的元素按FIFO(先进先出)排序。队头是在队列中停留最长时间的元素。队尾是在队列中停留时间最短的元素。新元素插入到队列的尾部,并且队列检索操作在队列的头部获取元素。
  这是一个经典的“有界缓冲区”,其中固定大小的数组包含由生产者插入并由消费者提取的元素。创建后,容量将无法更改。试图将一个元素放入一个已满的队列将导致操作阻塞;试图从空队列中取出一个元素也会阻塞。
  这个类支持一个可选的公平性策略,用于对等待的生产者和消费者线程进行排序。默认情况下,不保证这个顺序。然而,将公平性设置为true的队列将按FIFO顺序授予线程访问权。公平性通常会降低吞吐量,但会降低可变性并避免饥饿。
  
(2)LinkedBlockingQueue无界队列
  LinkedBlockingQueue是一个基于链表实现的可选边界的阻塞队列
  “有界”的阻塞安全队列,其底层使用的是链表的数据结构。所谓的“有界”是因为,默认队列的大小是Integer.MAX_VALUE。这个数值等于21亿+。因为这个数据太大了,也可以理解为无界的。不建议使用默认值,最好在初始化的时候,指定队列的大小。
  
(3)PriorityBlockingQueue
  PriorityBlockingQueue是一个无界阻塞队列,它使用与PriorityQueue相同的排序规则,并提供阻塞检索操作。是一个支持优先级的无界队列。支持优先级是因为使用了comparator这个接口。默认采用字典升序排序策略的。如果不想使用默认的,在初始化的时候,还可以自定义比较器的。
  
(4)DelayQueue
  是一个支持优先级的无界阻塞队列。支持优先级是应该底层使用的是PriorityQueue队列来实现的。而PriorityQueue队列在添加元素的时候使用了siftUpComparable方法。这个队列的一个特点:支持延时获取。所以,这个队列可以运用在缓存系统的设计中。当从队列中获取到数据,说明延时时间到了。
  
(5)SynchronouseQueue同步队列
  是一个无存储空间的阻塞同步队列。不存储元素的原因是因为,一个put操作必须等待一个take操作与之对应才可以。否则就不能继续添加元素了。默认使用非公平的。在性能上SyncQueue队列的吞吐量比LBqueu和ABQueue的性能高。
(6)LinkedTrnsferQueue
  由链表组成的无界队列。比其他队列多了两个方法:tryTransfer、transfer。
  
(7)LinkedBlockingDeque
  链表组成的双端队列。For/Join框架中有涉及到这个队列。
在这里插入图片描述

2、非阻塞队列
(1)ConcurrentLinkedQueue

(2)PriorityQueue(优先级队列)
  PriorityQueue是一个无界优先级队列是基于优先级的。优先级队列中的元素根据自然顺序进行排序,或者通过在队列构建时提供的Comparator进行排序,当然这取决于使用哪种构造函数。优先级队列不允许空(null)元素。一个依赖自然顺序的优先级队列也不允许插入不可比较的对象。
  PriorityQueue的队头元素是最小的元素,如果有多个元素并列最小,那么队头是它们其中之一。
  PriorityQueue是无界的,但是有一个内部容量来控制用于在队列上存储元素的数组的大小。它总是至少与队列大小一样大。将元素添加到优先级队列时,其容量会自动增长。

3、双端队列
  Deque(double-ended queue,双端队列)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

四、AbstractQueuedSynchronizer

AbstractQueuedSynchronizer提供了一个框架来实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关的同步器(信号灯,事件等)。
  该类旨在为大多数依赖单个原子int值表示状态的同步器提供有用的基础。子类必须定义更改此状态的受保护方法,并定义该状态对于获取或释放此对象而言意味着什么。
  鉴于这些,此类中的其他方法将执行所有排队和阻塞机制。子类可以维护其他状态字段,但是仅跟踪关于同步的使用方法getState(),setState(int)和compareAndSetState(int,int)操作的原子更新的int值。

五、小结

1、Queue是一个集合,队列的每个方法都有两种形式,一种是抛异常,另一种是返回一个特定的值。
2、PriorityQueue是一个无界优先级队列,默认情况下,队列中的元素按自然顺序排序,或者根据提供的Comparator进行排序。也就是说,优先级队列中的元素都是经过排序的,排序规则可以自己指定,同时队列中的元素都必须是可排序的。
3、BlockingQueue是一个阻塞队列,向已满的队列中插入元素时会阻塞,向空队列中取元素时也会阻塞;阻塞队列被设计主要用于生产者-消费者队列。
4、ArrayBlockingQueue是用数组实现的有界阻塞队列,队列中的元素按FIFO(先进先出)排序。
5、LinkedBlockingQueue是用链表实现的可选边界的阻塞队列。
6、PriorityBlockingQueue相当于是阻塞队列和优先级队列的合体,排序规则与优先级队列相同。
7、DelayQueue延时队列中的元素都有一个有效期,只有当过了有效期才可以使用该元素。

参考文章:
《Java 中的各种队列使用总结》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值