Java版数据结构队列
Posted chenry777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java版数据结构队列相关的知识,希望对你有一定的参考价值。
本文所有代码已上传github: https://github.com/chenruoyu0319/data-structure-for-java/tree/main/%E9%98%9F%E5%88%97
1.队列的定义
定义:队列是一种特殊的线性表,特殊之处在于它只允许在表(线性表)的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾(线性表尾端),进行删除操作的端称为队头(线性表前端)。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表,与栈的(LIFO)正好相反。
队列这个概念非常好理解。你可以把它想成排队买票,先来的先买,后来的人只能站末尾,不允许插队。先进者先出,这就是典型的“队列”。
2.队列的特点
(1)由线性表构成:链表或者数组
(2)FIFO
3.队列的分类
(1)顺序(单向)队列:(Queue) 只能在一端插入数据,另一端删除数据
生活场景:排队,尾部排入头部走出
(2)循环(双向)队列(Deque):每一端都可以进行插入数据和删除数据操作
(3)循环单向队列、非循环双向队列
4.队列的基本操作
我们知道,栈只支持两个基本操作:入栈push()和出栈pop()。
队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:
入队enqueue(),放一个数据到队列尾部;
出队dequeue(),从队列头部取一个元素。
所以,队列跟栈一样,也是一种操作受限的线性表数据结构。作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列、阻塞队列、并发队列。它们在很多偏底层系统、框架、中间件的开发中,起着关键性的作用。
5.单向队列的实现方式
顺序队列(数组)
链式(链表)
6.循环队列的实现方式
怎么判断队列已经满了?
两种方法:
1.加了一个实际的size变量就可以了。
画一个循环队列满了的图。
2.判断满:(tail+1)%n==head
怎么判断空?tail==head
7.优先队列
回到排队的场景,有些vip客户,总是可以插队。抽奖的时候,
普通用户,vip用户,svip用户。
优先队列:其实就是在插入的时候排了序而已
8.阻塞队列
此种具有特殊特性的队列应用却比较广泛,比如阻塞队列和并发队列。阻塞队列其实就是在队列基础上增加了阻塞操作。简单来说,就是在队列为空的时候,从队头取数据会被阻塞。因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后再返回。
阻塞队列的应用实例:线程池
线程池里面当任务满时,此时又来一个任务,线程池是如何处理的?具体有哪些策略?这些策略又是
如何实现的?
触发拒绝策略的条件:当线程池的任务缓存队列已满,并且线程池中的线程数目达到maximumPoolSize时,
如果还有任务到来就会采取任务拒绝策略,即会先存缓存队列。
队列:阻塞队列,线程有空闲的时候再从里面拿,就是take/put,如果在公平的情况下,肯定是FIFO,就是我们的队列。
一个是无限的排队队列(链表,千万别用,linkedBlockingQueue),还有一种就是有界(用数组实现,ArrayBlockingQueue),
只处理开的空间大小,多了的继续抛出去异常(丢弃)。
在一些小型系统,知道数据需求量不大,可以用LinkBlokingQueue,用ArrayBlockingQueue就行了
有几种拒绝策略:
1、AbortPolicy:该策略是直接将提交的任务抛弃掉,并抛出RejectedExecutionException异常。
2、DiscardPolicy:该策略也是将任务抛弃掉(对于提交的任务不管不问,什么也不做),不过并不抛出异常。
3、DiscardOldestPolicy:该策略是当执行器未关闭时,从任务队列workQueue中取出第一个任务,并抛弃这第一个任务,进而有空间存储刚刚提交的任务。使用该策略要特别小心,因为它会直接抛弃之前的任务。
4、CallerRunsPolicy:该策略并没有抛弃任何的任务,由于线程池中已经没有了多余的线程来分配该任务,
该策略是在当前线程(调用者线程)中直接执行该任务。
以上是关于Java版数据结构队列的主要内容,如果未能解决你的问题,请参考以下文章