`

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系列教程》:

 

0
2
分享到:
评论

相关推荐

    java Maven中常用命令和插件

    java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用命令和插件java Maven中常用...

    JAVA中常用的数据结构

    JAVA中常用的数据结构是Java开发者不可或缺的基础知识,以下将对JAVA中常用的数据结构进行详细的介绍。 Collection接口 Collection接口是JAVA中所有集合类的父接口,它提供了基本的集合操作方法,如add、remove、...

    java中常用日语词汇

    Java 中常用日语词汇 Java 是一种广泛应用于软件开发的编程语言,日本企业在开发 Java 项目时经常使用的一些日语词汇。本文档整理了一些常用的日语词汇,旨在帮助开发者更好地理解和使用 Java 相关技术。 计算机...

    Java中常用类API.ppt

    Java中常用类API.ppt

    JAVA面试题(Zookeeper、消息队列、分布式等最新的也有)

    首先,Zookeeper是Apache Hadoop的一个子项目,它是一个分布式的,开放源码的分布式应用程序协调服务。Zookeeper提供了诸如命名服务、配置管理、集群同步、分布式锁和领导者选举等功能。在Java面试中,理解Zookeeper...

    Java中常用字符串方法总结.doc

    Java 中常用字符串方法总结 Java 中的字符串是极其重要的数据类型之一,字符串的操作和处理在 Java 开发中占据着非常重要的地位。下面是 Java 中常用字符串方法的总结。 创建并初始化字符串 在 Java 中,可以使用...

    java中常用类,String,Math等

    java中常用类,String,Math等

    java中常用字符串方法总结

    在Java编程语言中,字符串是极其重要...以上就是Java中常用字符串方法的总结。理解并熟练运用这些方法,将极大地提升你在处理字符串时的效率和代码质量。在实际开发中,还需要结合具体需求灵活选择和组合使用这些方法。

    在java中常出现的错误

    在java中常出现的错误

    Java中常量分类.pdf

    本篇将详细介绍Java中的五种常量类型:整型常量、浮点型常量、字符型常量、布尔型常量以及字符串型常量。 1. **整型常量** 整型常量用于表示整数,Java提供了三种表示形式: - 十进制:由0到9的数字组成,但第一...

    java中常用命令的详解以及包与目录详解

    例如,如果你有一个源文件`com.mypackage.MyClass.java`,可以使用`-d`选项指定输出目录: ```bash javac -d /path/to/output com/mypackage/MyClass.java ``` 这将创建`/path/to/output/com/mypackage`目录并把`...

    java web开发中常遇到的问题

    Java Web 开发中常遇到的问题 在 Java Web 开发中,开发者经常会遇到一些棘手的问题,影响项目的进度和质量。在这篇文章中,我们将列举一些常见的问题,并对其进行解释和解决。 1. java.lang....

    什么是Java的数据库连接技术?Java中常用的数据库连接方式有哪些?(java面试题附答案).txt

    ### Java中常用的数据库连接方式 #### JDBC (Java Database Connectivity) **定义与作用:** JDBC 是 Java 提供的一套标准数据库访问 API,它支持与各种关系型数据库进行交互。通过 JDBC,开发者可以使用统一的...

    Java中常用的数据库连接池[定义].pdf

    本文将详细介绍Java中常用的数据库连接池,包括它们的工作原理、特点以及主要配置。 1. 数据库连接池的原理 数据库连接池的基本思想是在系统启动时预先创建一定数量的数据库连接并存储在内存中。当应用程序需要访问...

    浅谈Java中常用数据结构的实现类Collection和M

    本篇文章将深入探讨两个重要的数据结构实现类:Collection和Map,以及它们在Java中的应用。 首先,Collection是Java集合框架的顶层接口,它是所有单值容器的父接口。Collection接口定义了对一组对象进行操作的基本...

    JAVA对象以及数据的工具类

    本篇文章将深入探讨Java中的对象、基础类型以及数据处理相关的工具类。 首先,让我们关注Java中的基础类型。Java有八种原始数据类型:byte、short、int、long、float、double、char和boolean。为了方便处理这些类型...

    java开发中常使用的JAR包,减少您网上搜索的时间

    标题提到的"java开发中常使用的JAR包"集合提供了一站式的解决方案,免去了开发者在网上寻找和验证各种依赖的繁琐工作。这些JAR包涵盖了从基础功能到特定任务处理的各种组件,极大地丰富了Java的开发环境。 首先,...

    给你精讲面试中常出现的261个Java语言问题

    给你精讲面试中常出现的261个Java语言问题

    java的常用的获取时间的方法

    本文将详细介绍Java中常用的时间处理方法,特别是基于`java.util.Date`、`java.text.SimpleDateFormat`、`java.util.Calendar`等类的操作,以及如何通过这些方法获取当前时间、计算日期差、获取周、月、年的第一天和...

    java Library.java

    Java 图书馆管理程序是一个基于Java编程语言开发的应用软件,主要功能是协助图书馆进行书籍的录入、查询、借阅和归还等日常管理工作。在Java技术框架下,这样的程序通常会利用面向对象的设计原则和模式,以提高代码...

Global site tag (gtag.js) - Google Analytics