4.4队列笔记

队列,一种操作受限的线性表结构,尾部入队,头部出队,特点是先进先出(顺序线性表)

1.队列实现

顺序队列,链式队列

2.入队出队操作

初始化head=tail=0,用head出队,tail入队,但是当tail到达内存末尾,但是head并不在原点(内存中还有空闲位置,但是没法插入了)

注:

方法一,类似数组删除操作,有空隙不连续,这种情况都用数据搬移即刻解决,而且不用每次入队都保证连续,只需要到达内存尾部才触发一次数据搬移操作(整体平移到原点)

方法二,循环队列直接避免数据搬移,循环队列长度设定需要对并发数据有一定的预测(否则丢失太多请求),但最关键的是,判断队空队满的判定情况(专门牺牲一个内存区别空满)

head==tail;(空就是收尾只差为0)

tail==n;(满到达内存尾部)

head==tail;(空就是收尾只差为0)

(tail+1)%n=head;(满牺牲一个,专门区分空满状态,顺便可用存大小)

3.阻塞队列和并发队列

阻塞队列:在队列基础上,增加了阻塞功能,空则阻塞出队,满则阻塞入队,轻松实现生产者-消费者模型(一可协调生产消费速度,二可协调消费生产者个数,如一生产多消费),也引出多线程问题,保证线程安全问题,可用并发队列实现

并发队列:a.直接在 enqueue()、dequeue() 方法上加锁,但是锁粒度大并发度会比较低,同一时刻仅允许一个存或者取操作;b.基于数组的循环队列,利用 CAS 原子操作,可以实现非常高效的并发队列。这也是循环队列比链表队列应用更广的原因。

4.经典问题线程池

线程池没有空闲线程时,新的任务请求线程资源时,线程池该如何处理,有哪些策略?各种处理策略又是如何实现的呢?

答:一般有两种处理策略。

第一种是非阻塞的处理方式,直接拒绝任务请求;另一种是阻塞的处理方式,将请求排队,等到有空闲线程时,取出排队的请求继续处理。

若用非阻塞处理,那如何存储排队的请求呢?

答:希望公平地处理每个排队的请求,先进者先服务,所以队列这种数据结构很适合来存储排队请求,队列有基于链表和基于数组这两种实现方式。

链表数组队列应用区别?

答:关键看对响应时间要求

基于链表实现的无界队列(unbounded queue),但是过多的请求排队等待,请求处理的响应时间过长。

基于数组实现的有界队列(bounded queue),线程池中排队的请求超过队列大小时,接下来的请求就会被拒绝,这种方式对响应时间敏感的系统来说,就相对更加合理。这时候设置一个合理的队列长度非常重要,太大等待长,太小浪费资源

注:大部分资源有限的场景,在没有空闲资源时,基本都使用队列实现请求排队

5.其他应用

数据库连接池,消息队列

5.生活小秘招区别栈和队列

吃多了拉就是队列,吃多了吐就是栈,talk is cheap,show me the code(屁话少说,放马过来)

你可能感兴趣的:(4.4队列笔记)