您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

阻塞队列实现生产者消费者以及同步工具类

时间:2020-06-24 13:37:03  来源:  作者:

要学习多线程一些基本的同步类也是不得不学习的,这里主要讲一点基本的概念与使用。

阻塞队列

阻塞队列提供可阻塞的put和take方法,支持定时的offer和poll方法,如果队列已经满了,那么put方法将阻塞直到有空间可用;如果队列为空,那么take方法将会阻塞直到有元素可用;同时队列可以是有界也可以是无界的,无界队列永远都不会充满,因此无界队列的put方法永远不会阻塞;

JAVA中的阻塞队列主要有以实现BlockingQueue接口的几个类,其中LinkedBlockingQueue、ArrayBlockingQueue对应LinkedList与ArrayList,他们是先进先出队列(FIFO);阻塞队列能够实现生产者与消费者的关系,生产者往队列中put数据,而消费者往take中拉取数据,进而实现异步操作。曾经的生产中的例子简化后如下图:

阻塞队列实现生产者消费者以及同步工具类

 

队列还有一些实现比如:

PriorityBlockingQueue队列是优先级队列,根据元素的比较来控制顺序;

SynchronousQueue队列维护的不是元素而是线程,这些线程在等待把元素加入或者移除队列,就好像餐馆出菜,前面的队列都是把菜炒好了放到放菜的地方,服务员一个一个拿走,而SynchronousQueue则没有放菜的地方,厨师炒好菜直接给服务员端走,所以SynchronousQueue要求消费者足够多,并且总是有至少一个消费者在等待才适合用。

同步工具类

闭锁

闭锁:可以延迟线程的进度直到其到达终止状态。闭锁相当于一个闸门,在闭锁到达结束状态之前,这个闸门一直是关闭的,任何线程都不能通过当到达结束状态时,闸门允许所有线程通过,闭锁到达结束状态后不会再改变状态闭锁。

闭锁主要作用是可以用来确保一些活动直到其他活动都完成后才继续执行。比如一个初始化需要等另一个初始化,比如所有玩家都准备才开始。

CountDownLatch是一种闭锁实现,它初始化一个正数,countDown方法使数字递减,await方法使线程等待计数器到0,否则阻塞,示例如下图:

阻塞队列实现生产者消费者以及同步工具类

 

这个方法主要用来统计一个任务在多个线程同步执行下消耗时间,利用两个闭锁实现了线程先一起准备好,然后放开开始闭锁,所有线程一起执行,每个线程最后都会countDown一下结束闭锁,当所有线程执行完成结束闭锁也就方法,这样就可以实现统计所有线程一起执行消耗的时间。

FutureTask

FutrueTask是一个实现了Runnable的类,并且它可以获取到线程的执行结果,get方法执行取决于任务的状态,如果任务已经完成,那么get会立即返回结果,否则get将

阻塞直到任务进入完成状态,可以利用它的这个功能来实现闭锁

它还可以用来异步提前计算一些比较耗性能的值,比如一个操作比较耗性能那么可以让它先执行,等到需要计算的结果的时候在get。

信号量

计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量

实现原理是:Semaphore管理着一组虚拟的许可,执行操作前必须先acquire获得许可,这个许可就减一,如果许可被减到0,线程再来获取许可就阻塞等待其他线程在操作完成后release释放许可;

比如初始化了一定数量的数据库线程池,每个线程获取线程池时先acquire,如果获取成功说明有线程继续执行,如果没有线程了acquire方法会阻塞等待有多余线程。

还可以把计数信号量的数量设置为1,那么只要有一个线程acquire成功,其他线程就只能等待直到线程release,这样就实现了一个互斥锁。

栅栏

栅栏类似于闭锁,他也是阻塞一组线程直到某个事件发生,区别在于栅栏是等待所有线程到达指定,而闭锁是等待一个事件,闭锁是一次性的不会重置。闭锁是等待其他线程执行完成等待线程才开始执行,而栅栏是让每个线程都等待,直到所有线程都是等待状态,那么所有线程一起继续执行

可能有点不好理解,通过下面一个例子和闭锁例子进行对比,示例如下图:

阻塞队列实现生产者消费者以及同步工具类

 

不管执行多少次,一定是所有的"开始"打印完成后才会打印"结束",并且如果线程的数量没有初始化栅栏的值多,所有线程都会处于阻塞状态。

总结

今天总结了一点阻塞队列的知识和应用,平时一些消耗性能而创建线程去异步执行可能会造成线程太多的情况,可以简单的通过阻塞队列来实现生产者消费者的方式来解决问题。

还总结了一点同步工具类的知识,主要是理解这些基本概念和使用场景,闭锁通过触发countDown来减少计数器,当计数器减到0,await方法放行。信号量则是acquire方法去获取release方法去释放,栅栏则是先运行到await地方的线程先等待,等到所有线程都到了再一起执行,尤其要理解闭锁和栅栏的区别。

闭锁用来确保一些活动执行完成才执行一些操作,信号量用来保证某些操作的数量,栅栏用来等待所有操作一起到达指定点再一起继续执行。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!



Tags:阻塞队列   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事。 阻塞队列也就是 BlockingQueue ,这个类是一个接 口,同时继承了 Queue 接口,这两个接口...【详细内容】
2020-11-16  Tags: 阻塞队列  点击:(57)  评论:(0)  加入收藏
日常需求开发过程中,不免会遇到需要通过代码进行异步处理的情况,比如批量发送邮件,批量发送短信,数据导入,为了减少用户的等待,不希望一直菊花转啊转,因此需要进行异步处理,做法就是...【详细内容】
2020-08-02  Tags: 阻塞队列  点击:(65)  评论:(0)  加入收藏
要学习多线程一些基本的同步类也是不得不学习的,这里主要讲一点基本的概念与使用。阻塞队列阻塞队列提供可阻塞的put和take方法,支持定时的offer和poll方法,如果队列已经满了,那...【详细内容】
2020-06-24  Tags: 阻塞队列  点击:(50)  评论:(0)  加入收藏
一、阻塞队列简介阻塞队列常用于生产者和消费者场景,生产者往往是往队列里添加元素的线程,消费者是从队列里拿元素的线程吗,阻塞队列就是生产者存放元素的容器,是消费者拿元素...【详细内容】
2019-09-23  Tags: 阻塞队列  点击:(141)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条