前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发阻塞队列(BlockingQueue)— 生产者消费者模式核心部件

并发阻塞队列(BlockingQueue)— 生产者消费者模式核心部件

原创
作者头像
码农架构
修改2021-01-14 18:07:28
1.2K0
修改2021-01-14 18:07:28
举报
文章被收录于专栏:码农架构

在分析阻塞队列之前我们先看生产者消费者模式,这是一个很常见的模式,生产者负责数据的生产,而消费者则负数据的消费。一般来说生产者与消费者的数量比例是m:n,该模式最大的好处就是将数据生产方与消费方进行了解耦,使得它们之间不会互相影响。为了将生产者和消费者连接起来,我们需要一个特殊的容器,该容器能存储生产者生产的数据,而消费者则能从该容器中取出数据。

我们可以通过厨师、桌子、顾客来说明生产者消费者模式,厨师就好比生产者,他们制作生产出来美食将放到桌子这个容器中,顾客则好比是消费者,他们从桌子上取出美食进行消费享用。

阻塞队列

生产者消费者模式的核心部分就是生产者和消费者之间的那个特殊容器,我们通过实现一个线程安全且具有一定策略的容器便连接起两端的生产者和消费者。这个容器可以具有队列性质,也可以具有栈性质,亦或是其它数据结构。最常见的就是阻塞队列,队列保证了先进的数据先出,而阻塞则是队列已满时和队列为空时的处理策略,即队列已满时的入队操作和队列为空时的出队操作都会引起阻塞。

下图是阻塞队列工作示意图,线程一、线程二、线程三生产的数据通过put操作进行入队,线程四、线程五通过take操作进行出队,当队列满时put操作会阻塞等待消费者将队列的元素拿走,当队列为空时take操作会阻塞等待生产者将数据入队。

模拟实现

根据前面对阻塞队列的介绍,我们试着来模拟实现一个简单的阻塞队列。先看数据结构的设计,可以使用一个数组来存放队列的元素,并通过head和tail指针来约束先进先出规则。入队操作使用tail指向的位置,而出队则使用head指向的位置,一旦到达数组尾部就重新从头开始。

下面看看具体的实现,Object数组用于保存元素,size表示队列的大小,此外还有head和tail指针。通过构造函数来指定阻塞队列大小,生产者生产的数据调put方法进行入队,如果size等于队列最大长度时则调用wait阻塞(此时队列已经满了),否则将元素保存到队列中,同时维护size和tail,最后如果size等于1时要调用notifyAll方法通知消费者可以消费了。消费者通过调用take方法进行数据消费,如果size等于0时则调用wait阻塞(队列为空需要等待),否则通过head获取队列头的元素,同时维护size和head,最后如果size等于queue.length-1时调用notifyAll方法通知生产者可以生产了。

阻塞队列模拟实现

可以通过下面这个例子看模拟阻塞队列例子,输出结果如下,一个线程进行数据生产,一个线程进行数据消费。

BlockingQueue 接口

接下去我们看JDK  的阻塞队列接口BlockingQueue,该接口早在 Java 5 时就已经引入了。JDK为我们提供了很多种阻塞队列的实现,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue以及SynchronousQueue等等,它们都实现了BlockingQueue接口。该接口主要的核心方法如下,这些方法都支持中断,其中put方法和take方法我们都很熟悉的了,另外offer和poll两个方法其实对应的是put和take两个方法,只是它们提供了阻塞超时机制。

总结 

本节讲解了生产者消费者模式,该模式的核心部件是一种特殊的容器,而阻塞队列则是异常很常见的容器。然后我们通过一个数组和head、tail指针来模拟实现一个阻塞队列,其中put和take操作使用了synchronized控制多线程的访问,阻塞机制也由它提供。最后我们简单介绍了JDK的BlockingQueue接口,后面再分几个章节来详细分析ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue以及SynchronousQueue等阻塞队列的实现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 阻塞队列
  • 模拟实现
  • 阻塞队列模拟实现
  • BlockingQueue 接口
  • 总结 
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档