ArrayBlockingQueue和LinkedBlockingQueue的使用
BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞。
ArrayBlockingQueue是一个由数组支持的有界阻塞队列。在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。
基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。而LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。
ArrayBlockingQueue和LinkedBlockingQueue的区别:
1. 队列中锁的实现不同
ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁;
LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock
2. 在生产或消费时操作不同
ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会影响性能
3. 队列大小初始化方式不同
ArrayBlockingQueue实现的队列中必须指定队列的大小;
LinkedBlockingQueue实现的队列中可以不指定队列的大小,但是默认是Integer.MAX_VALUE
- public class BlockingQueueTest {
- private static ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5, true); //最大容量为5的数组堵塞队列
- //private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(5);
- private static CountDownLatch producerLatch; //倒计时计数器
- private static CountDownLatch consumerLatch;
- public static void main(String[] args) {
- BlockingQueueTest queueTest = new BlockingQueueTest();
- queueTest.test();
- }
- private void test(){
- producerLatch = new CountDownLatch(10); //state值为10
- consumerLatch = new CountDownLatch(10); //state值为10
- Thread t1 = new Thread(new ProducerTask());
- Thread t2 = new Thread(new ConsumerTask());
- //启动线程
- t1.start();
- t2.start();
- try {
- System.out.println("producer waiting...");
- producerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
- System.out.println("producer end");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- try {
- System.out.println("consumer waiting...");
- consumerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
- System.out.println("consumer end");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- //结束线程
- t1.interrupt();
- t2.interrupt();
- System.out.println("end");
- }
- //生产者
- class ProducerTask implements Runnable{
- private Random rnd = new Random();
- @Override
- public void run() {
- try {
- while(true){
- queue.put(rnd.nextInt(100)); //如果queue容量已满,则当前线程会堵塞,直到有空间再继续
- //offer方法为非堵塞的
- //queue.offer(rnd.nextInt(100), 1, TimeUnit.SECONDS); //等待1秒后还不能加入队列则返回失败,放弃加入
- //queue.offer(rnd.nextInt(100));
- producerLatch.countDown(); //state值减1
- //TimeUnit.SECONDS.sleep(2); //线程休眠2秒
- }
- } catch (InterruptedException e) {
- //e.printStackTrace();
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
- //消费者
- class ConsumerTask implements Runnable{
- @Override
- public void run() {
- try {
- while(true){
- Integer value = queue.take(); //如果queue为空,则当前线程会堵塞,直到有新数据加入
- //poll方法为非堵塞的
- //Integer value = queue.poll(1, TimeUnit.SECONDS); //等待1秒后还没有数据可取则返回失败,放弃获取
- //Integer value = queue.poll();
- System.out.println("value = " + value);
- consumerLatch.countDown(); //state值减1
- TimeUnit.SECONDS.sleep(2); //线程休眠2秒
- }
- } catch (InterruptedException e) {
- //e.printStackTrace();
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
- }
ArrayBlockingQueue和LinkedBlockingQueue的使用的更多相关文章
- ArrayBlockingQueue跟LinkedBlockingQueue的区别
.队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是t ...
- ArrayBlockingQueue和LinkedBlockingQueue分析
JAVA并发包提供三个常用的并发队列实现,分别是:ConcurrentLinkedQueue.LinkedBlockingQueue和ArrayBlockingQueue. Concurren ...
- JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue
JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...
- ArrayBlockingQueue和LinkedBlockingQueue的区别
ArrayBlockingQueue和LinkedBlockingQueue的区别,得出结论如下: 1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和 ...
- Java 容器源码分析之ArrayBlockingQueue和LinkedBlockingQueue
Java中的阻塞队列接口BlockingQueue继承自Queue接口. BlockingQueue接口提供了3个添加元素方法. add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会 ...
- ArrayBlockingQueue和LinkedBlockingQueue
1.BlockingQueue接口定义了一种阻塞的FIFO queue ArrayBlockingQueue和LinkedBlockingQueue的区别: 1. 队列中锁的实现不同 ArrayBlo ...
- ArrayBlockingQueue,LinkedBlockingQueue分析
BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...
- 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解
1. ArrayBlockingQueue简介 在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作.例如在“生产 ...
- java并发编程(二十四)----(JUC集合)ArrayBlockingQueue和LinkedBlockingQueue介绍
这一节我们来了解阻塞队列(BlockingQueue),BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,当容量满时往BlockingQ ...
随机推荐
- 关于编码和解码问题——encode、decode
一.背景和问题 近期在做一个关于声卡录音的项目,开发环境是win10 64位家庭中文版,pycharm2019.1,python3.6(Anaconda3),python模块pyaud ...
- 手把手教大家如何用scrapy爬虫框架爬取王者荣耀官网英雄资料
之前被两个关系很好的朋友拉入了王者荣耀的大坑,奈何技术太差,就想着做一个英雄的随查手册,这样就可以边打边查了.菜归菜,至少得说明咱打王者的态度是没得说的,对吧?大神不喜勿喷!!!感谢!!废话不多说,开 ...
- 【转】Kerberos简介
Kerberos协议: Kerberos协议主要用于计算机网络的身份鉴别(Authentication), 其特点是用户只需输入一次身份验证信息就可以凭借此验证获得的票据(ticket-grantin ...
- 在ASP.NET MVC中如何预防Cookie的窃取攻击(转载)
Cookie Cookie is a small piece of data sent by a web server to a web browser. The browser stores thi ...
- ORM单表查询,跨表查询,分组查询
ORM单表查询,跨表查询,分组查询 单表查询之下划线 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值models ...
- u库前戏
u库 ORM:对象关系映射 类 >>> 数据库的一张表 对象 >>> 表的一条记录 对象点属性 >>> 记录某一个字段对应的值 ''' 对象就是一 ...
- SpringMVC最详细笔记partⅠ
一.springMVC-quickStar 解决maven加载项目过慢 archetypeCatalog internal 导入依赖 <!-- 版本锁定 --> <propertie ...
- 如何使用 electron 屏幕或摄像头录制并保存到本地
思路分析 通过 electron desktopCapturer 和 navigator 获取要进行录制的媒体源信息: 使用 MediaRecorder 对视频流进行录制: 将 MediaRecord ...
- Rasa Stack:创建支持上下文的人工智能助理和聊天机器人教程
相关概念 Rasa Stack 是一组开放源码机器学习工具,供开发人员创建支持上下文的人工智能助理和聊天机器人: • Core = 聊天机器人框架包含基于机器学习的对话管理 • NLU = 用于自然语 ...
- Spring 事务注意事项
使用事务注意事项 1,事务是程序运行如果没有错误,会自动提交事物,如果程序运行发生异常,则会自动回滚. 如果使用了try捕获异常时.一定要在catch里面手动回滚. 事务手动回滚代码 Transact ...