Java中常用的七个阻塞队列介绍第一篇
Java中常用的七个阻塞队列介绍第一篇
在上一篇我们对Java中的队列分类做了简单的介绍。本文咱们主要来聊聊阻塞队列中的七个常用子类。这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个队列进行总结。最后在来个大总结。文章可能有点长,但是,大家耐着性子看完,保证你对这七大阻塞队列有深刻的理解。
本文主要内容:介绍前三个队列及查看源码总结每个队列的特点
本文出自凯哥Java(kaigejava)的《凯哥Java并发系列》之《Java并发编程之队列》系列的第二篇:《Java中常用的七个阻塞队列介绍第一篇》
先来看看这七个子类的类图:
都是BlockingQueue(阻塞队列的父接口)的子类,而BlockingQueue最终又继承于Collection接口。从而我们可以这么说,阻塞队列是Collection的子类的一个分支也没问题。
阻塞队列的七个子类:
ArrayBlockingQueue(下文简称:ABQueue)、LinkedBlockingQueue(下文简称:LBQueue)、PriorityBlockingQueue(下文简称:PBQueue)、DelayQueue(下文简称:DQueue)、SynchronouseQueue(下文简称:SyncQueue)、LinkedTrnsferQueue(下文简称:LTQueue)、LinkedBlockingDeque(下文简称:LBDeque)这个七个。我们来一个一个看。
ArrayBlockingQueue
在上面我们知道了阻塞队列是集合的一个子类。我们也知道: Collection<String> c1 = new ArrayList<String>();这个是成立的。那么是不是把ArrayList换成ArrayBlockingQueue也行呢?
我们测试下:
发现确实可以的。
我们来看看arrayBlockingQueue的构造器:
由三个构造器。代码如下:
我们看到,其实都调用的是:
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
从代码中我们可以看到:ABQueue底层是数组结构。使用的是ReentrantLock锁。再之前的文章中凯哥(凯哥Java:kaigejava)在讲解ReentrantLock的时候,讲过默认使用的是非公平的。
所以通过源码分析我们可以对ABQueue得到如下总结:
ABQueue结论:
ArrayBlockingQueue:是数据结构的有界的阻塞队列。且默认使用非公平锁,也就是不保证线程公平访问队列的。
为什么说是有界的呢?因为我们知道数组大小是有边界的。无论你声明的数组多大,最后都一个极限的。存在大小限制,从源码中,来看看向队列中添加数据的方法:
为什么说默认不保证线程公平呢?因为RLock默认使用的就是非公平机制的。
如何保证公平呢?在声明的时候,直接设置为true.
LinkedBlockingQueue
先来看看构造器:
和ABQueue类似都是由三个构造器。但是不同的是,LBQueue没有强制输入队列大小的。默认使用的是Integer.MAX_VALUE.那么这个数值是多大呢?2的31次方-1.大概是21亿多。
从源码中,我们可以看出,last=head=new Node<E>()。从这行代码中,我们可以知道,LBQueue使用的是链表结构。也是使用的RLock锁。
所以,从源码中,我们可以得到如下总结:
LBQueue结论:
LBQueue是使用链表结构的有界阻塞队列。
为什么说是有界的呢?我们来看看添加的元素的源码:
需要注意:千万别用默认的。因为默认大小是Integer.MAX_VALUE。java int 类整数的最大值是 2 的 31 次方 - 1 = 2147483648 - 1 = 2147483647。这个数据太大了。如果使用默认的话,也可以理解为无界的。
PriorityBlockingQueue
这个队列名字拆开:
priority:中文的意思是优先的,优先通行权。这个队列支持优先级的。
来看看构造器:
如果不传递队列数量。使用默认的。从源码中,我们可以看到默认创建初始的队列大小是11.
我们来看看添加元素方法的源码:
从源码中,我们可以到,在添加的时候用了Comparator这个接口。而且在源码中,我们也没看到对队列的大小限制。
PBQueue总结:
PBQueue是一个支持优先级的无界阻塞队列。默认情况下元素采用自然顺序升序排列。也可以自定义类来实现comparator接口的compare方法来实现自定义排序规则。或者是在初始化的时候调用public PriorityBlockingQueue(int initialCapacity,Comparator<? super E> comparator) {}这个构造器,支持在初始化的时候传递比较器。PBQueue队列同样使用了RLock,所以不能保证公平性。在添加的时候,不能添加null元素。否则会空指针异常。
为什么说支持优先级呢?添加元素的源码中使用了Comparator接口。而Comparator默认使用的是字典排序的。
代码演示
代码演示,PBQueue使用的默认排序顺序是字典排序升序法。代码如下:
运行结果:
下面来演示自定义比较器。
先来看看自定义的倒序排序器
在来看看存放和获取后:
ABQueue、LBQueue、PBQueue比较
名字 是否有界 数据结构 备注
ArrayBlockingQueue 有界的 数组 "初始化的时候需要给定队列大小;
默认非公平的。在初始化的时候可以给定是否使用公平锁"
LinkedBlockingQueue 有界的 链表 "默认大小事Integer.Max_value.达到21亿不建议使用默认的。"
PriorityBlockingQueue 无界的 链表 "支持优先级的阻塞队列。
默认适用自然排序升序规则
在初始化队列的时候,可以给定比较器的"
《Java并发编程-JUC系列教程》:

Java中常用的七个阻塞队列介绍第一篇的更多相关文章
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
- java中常用的几种缓存类型介绍
在平时的开发中会经常用到缓存,比如locache.redis等,但一直没有对缓存有过比较全面的总结.下面从什么是缓存.为什么使用缓存.缓存的分类以及对每种缓存的使用分别进行分析,从而对缓存有更深入的了 ...
- Java中常用七个阻塞队列的总结
Java队列总结 通过前面文章的学习,我们对Java中常用队列做了介绍.本文,咱们来对队列做个总结吧. 首先,我们介绍了现实生活中的实际场景(排队买票等),来告诉我们为什么需要使用队列. 队列是一种先 ...
- java中常用的工具类(三)
继续分享java中常用的一些工具类.前两篇的文章中有人评论使用Apache 的lang包和IO包,或者Google的Guava库.后续的我会加上的!谢谢支持IT江湖 一.连接数据库的综合类 ...
- Java多线程高并发学习笔记——阻塞队列
在探讨可重入锁之后,接下来学习阻塞队列,这边篇文章也是断断续续的写了很久,因为最近开始学ssm框架,准备做一个自己的小网站,后续可能更新自己写网站的技术分享. 请尊重作者劳动成果,转载请标明原文链接: ...
- 动图+源码,演示Java中常用数据结构执行过程及原理
最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想用动画来绘制数据流转过程. 主要基于jdk8, 可能会有些特性与jdk7之前不相同, 例如LinkedList Linke ...
- 动图+源码,演示 Java 中常用数据结构执行过程及原理
阅读本文大概需要 3.7 分钟. 作者:大道方圆 cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想 ...
- Java并发编程(十)阻塞队列
使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦.但是有了阻塞队列就不一样了, ...
- Java并发(7):阻塞队列
在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...
随机推荐
- 文本编辑器之kindeditor
摘要:最近在自己学习搭建网站的时候,突然要搭建网站的时候发现了一个好东西,那就是kindeditor这个文本编辑器,这个编辑器简单好用,而且很小,并且是开源的. 文本编辑器介绍 KindEditor ...
- POJ1270 toposort+DFS+回溯
题目链接:http://poj.org/problem?id=1270 这道题其实就是求所有满足条件的topo序,我们考虑到给定的字符是确定的,也就是他们的长度都是一样的,所以为了得到所有的情况,我们 ...
- [模板] trie树 (字典树)
本文基于https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html #include<bits/stdc++.h> using name ...
- 浅析二分搜索树的数据结构的实现(Java 实现)
目录 树结构简介 二分搜索树的基础知识 二叉树的基本概念 二分搜索树的基本概念 二分搜索树的基本结构代码实现 二分搜索树的常见基本操作实现 添加操作 添加操作初步实现 添加操作改进 查询操作 遍历操作 ...
- 学习GAN必须阅读的10篇论文
本文转载自:魔图互联.欢迎访问网站查看详细教程:Tensorflow(pytorch)系列教程 生成对抗网络是深度学习中最有趣和最受欢迎的应用之一.本文将列出 10 篇关于 GAN 的论文,这些论文详 ...
- 83 项开源视觉 SLAM 方案够你用了吗?
作者:吴艳敏 来源:83 项开源视觉 SLAM 方案够你用了吗? 前言 1. 本文由知乎作者小吴同学同步发布于https://zhuanlan.zhihu.com/p/115599978/并持续更新. ...
- 【WPF学习】第六十章 创建控件模板
经过数十天的忙碌,今天终于有时间写博客. 前面一章通过介绍有关模板工作方式相关的内容,同时介绍了FrameWorkElement下所有控件的模板.接下来将介绍如何构建一个简单的自定义按钮,并在该过程中 ...
- Math对象常用方法介绍
<script> /* 001-Math.abs() 绝对值 */ console.log(Math.abs(123), Math.abs(-998), ...
- spring 事务源码赏析(一)
在本系列中,我们会分析:1.spring是如何开启事务的.2.spring是如何在不影响业务代码的情况下织入事务逻辑的.3.spirng事务是如何找到相应的的业务代码的.4.spring事务的传播行为 ...
- MySQL出现的问题
错误展示 今天还是老样子照常启动MySQL WorkBench的时候出了错误,无法连接服务器 CMD登陆也不行 发现mysql的服务都没启动,于是点击启动,却又报这个错 cmd查看MySQL的日志,想 ...