队列:生产消费模式及线程池的运用
> 关注公众号 MageByte,设置星标获取最新干货。 “加群” 进入技术交流群获更多技术成长。
向固定大小的线程池投放请求任务时,若果线程池中没有空闲资源了,这时候还有新的请求进来,线程池如何处理这个请求?拒绝请求还是排队?使用怎样的处理机制
一般两种策略:
直接拒绝任务请求;
将请求排队,等有空闲线程的时候取出排队的请求继续处理。
那如何存储排队的请求呢?这就是今天要讲的话题。
其底层的数据结构就是今天我们要讲的内容,「队列」Queue。
完整代码详见 GitHub:https://github.com/UniqueDong/algorithms.git
什么是队列
用一个生活例子,可以想象成超市排队结账,先来的先结账,后面的人只能站在末尾,不允许插队。先进先出,这就是所谓的「队列」
队列是一种线性数据结构,队列的出口端叫「队头」,队列的入口端叫「队尾」。
与栈类似队列的数据结构可以使用数组实现也可以使用链表实现。关于栈的内容同学们可以翻阅历史文章学习「栈:实现浏览器前进后退」,队列最基本的操作也是两个:入队 (enqueue) ,将新元素放到队尾;出队 (dequeue),从队头移除元素,出队元素的下一个元素变成新的队头。
作为基础的数据结构,队列的应用也很广泛,尤其是一些特定场景下的队列。比如循环队列、阻塞队列、并发队列。它们在很多偏底层系统、框架、中间件的开发中,起着关键性的作用。比如高性能队列 Disruptor、Linux 环形缓存,都用到了循环并发队列;Java concurrent 并发包利用 ArrayBlockingQueue 来实现公平锁等。
队列也是一种操作受限的线性表数据结构。
顺序队列与链式队列
队列是跟栈一样,是一种抽象的数据结构。 具有先进先出的特性,在队头删除数据,在队尾插入数据。
可以使用数组实现,也可以使用链表实现。使用数组实现的叫 顺序队列,用链表实现的 叫 链式队列。
顺序队列
一起先来看数组实现的队列:
出队操作就是把元素移除队列,只允许在队头移除,出队的下一个元素成为新的队头。
入队操作就是把新元素放入队列,只允许在队尾插入,新元素的的下一个位置成为队尾。
随着不停地进行入队、出队操作,head 和 tail 都会持续往后移动。当 tail 移动到最右边,即使数组中还有空闲空间,也无法继续往队列中添加数据了。这个问题该如何解决呢?
当出现这种情况的时候我们就需要做数据迁移。如图所示:当 abcd 入队后,对应的指针位置。
现在我们执行出队操作
当我们调用两次出队操作之后,队列中 head 指针指向下标为 2 的位置,tail 指针仍然指向下标为 4 的位置。
迁移操作其实就是把整段数据移动到数组 0 开始的位置。
具体代码如下
/**
* 数组实现队列
*/
public class ArrayQueue
关于找一找教程网
本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[9.队列:生产者消费者模式]http://www.zyiz.net/tech/detail-133346.html