Java阻塞队列必看类:BlockingQueue快速了解大体框架和实现思路

 更新时间:2022年10月28日 10:00:23   作者:涝山道士  
这篇文章主要介绍了Java阻塞队列必看类:BlockingQueue快速了解大体框架和实现思路,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

前言

本文主要说明BlockingQueue类、阻塞队列使用的共同父类AbstractQueue的基础知识。后续将会逐渐探索BlockingQueue的所有实现类。

BlockingQueue

概览

1. 不接受null元素。

通过新增方法添加null元素时,会抛出空指针异常。因为null值将用作标记​​值,来指明poll操作失败。同时null值作为阻塞队列的元素也是无任何意义的。

2. 可以有容量限制,也可以没有。

当作为有界队列时,如果当队列空间不足时,add操作将会抛出IllegalStateException异常,offer将会返回false,put操作将会阻塞直到队列空间可用。

如果不设置容量大小,那么默认值是Integer.MAX_VALUE。此时可以看作无界队列;

虽然队列在逻辑上可以是无界的,但由于资源耗尽(导致OutOfMemoryError ),添加操作可能会失败。 

3. 用于生产者-消费者队列,但是同时也支持Collection的操作。

例如删除队列元素操作remove(e),但是这些操作的效率很低,一般仅用于删除某个临时取消的任务。

4. 所有实现都是线程安全的。

但是对于集合中的批量操作方法,如果其实现类没有特殊处理的话,那么addAll、containsAll、retainAll、removeAll等可能不会原子地执行。

5. 队列,整体上都基本准寻先进先出的访问顺序。

在整体上看,各个实现类是符合FIFO的顺序的。

主要实现类

  • LinkedBlockingQueue:链表式阻塞队列
  • ArrayBlockingQueue:数组式阻塞队列
  • PriorityBlockingQueue:优先级阻塞队列
  • LinkedBlockingDeque:阻塞型双端队列
  • DelayQueue:延时阻塞队列
  • SynchronousQueue:实时同步队列(没有任何存储元素的空间)
  • …………

BlockingQueue方法的四类形式

BlockingQueue的所有实现类的方法都分为如下四类。相对于其他的集合操作方法,put和take是实现阻塞操作的核心方法,需要重点关注。

  • Throws exception:操作未实现时(正常流程下的执行)抛出异常
  • Special value:根据操作的实际情况,返回特定值,例如null、false
  • Blocks:阻塞当前线程,直到当前线程可以成功执行
  • Times out:尝试指定时间后,放弃执行
 

Throws exception

Special value

Blocks

Times out

新增

add(E e)

offer(E e)

put(E e)

offer(E e, long timeout, TimeUnit unit)

删除

remove()

poll()

take()

poll(long timeout, TimeUnit unit)

查询

element()

peek()

  

BlockingQueue类确定了阻塞队列的整体框架,确定了各个方法的定义,因此也是了解阻塞队列一定要学习的类。

本文中大部分都是从源码注释中解读而来,同时也包含了一些自己的理解,如果表述有误,还望指出。

AbstractQueue

概览

AbstractQueue类,提供了一些Queue操作的骨架实现。

这里提及AbstractQueue的原因是,阻塞队列的大多实现类都继承该类,可以说,这个抽象类,实现了BlockingQueue的大部分通用功能。比如add、remove失败时抛出异常等等,下面会一一提及。

源码解析

这个类基本上搭建起了一个阻塞队列Throws exception形式的框架,它实现了各个抛出异常的方法。

各个方法都比较简单,关键在于了解其具体的实现思路。这对了解各个阻塞队列的实现类很有帮助。

  • add
    public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

当队列空间足够时,将直接插入成功。offer方法由具体的子类实现。

如果offer插入元素成功,则add返回true ,否则将抛出IllegalStateException异常。

  • remove
    public E remove() {
        E x = poll();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

检索并删除队列的队首元素。

它与poll不同之处仅在于,如果此队列为空,它会抛出NoSuchElementException异常。

删除成功后,返回删除的元素。

  • element
    public E element() {
        E x = peek();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

仅获取队列的队首元素并返回结果,并不进行操作。

与peek不同之处在于,如果此队列为空,它会引发NoSuchElementException异常。

  • clearaddAll
    public void clear() {
        while (poll() != null)
            ;
    } 
 
    public boolean addAll(Collection<? extends E> c) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

遍历添加或删除所有元素,实现挺简单的,不过这里并没有进行单个操作出现异常时的处理。

总结

阻塞队列了解得也差不多了,之前只是简单的学习了如何使用阻塞队列的方法,这次也是打算来一个全面深入的学习吧。知其然知其所以然,对于程序员还是蛮重要的。 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java设计模式之装饰模式详解

    Java设计模式之装饰模式详解

    这篇文章主要介绍了Java设计模式中的装饰者模式,装饰者模式即Decorator Pattern,装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能,装饰模式又名包装模式。装饰器模式以对客户端透明的方式拓展对象的功能,是继承关系的一种替代方案
    2022-07-07
  • Springmvc的运行流程图文详解

    Springmvc的运行流程图文详解

    今天小编就为大家分享一篇关于Springmvc的运行流程图文详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • springboot多数据源使用@Qualifier自动注入无效的解决

    springboot多数据源使用@Qualifier自动注入无效的解决

    这篇文章主要介绍了springboot多数据源使用@Qualifier自动注入无效的解决,具有很好的参考价值,希望对大家有所帮助。也希望大家多多支持脚本之家
    2021-11-11
  • 一文详解Spring构造函数推断

    一文详解Spring构造函数推断

    这篇文章主要介绍了Spring构造函数推断自动注入及底层原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加
    2023-04-04
  • 详解SpringBoot如何统一处理返回的信息

    详解SpringBoot如何统一处理返回的信息

    现在的项目是前后端开发的居多,那么我们怎么定义接口返回的数据,怎么使用 Spring Boot 来统一处理返回的信息呢,本文就来和大家简单讲讲
    2023-06-06
  • Java项目导入IDEA的流程配置以及常见问题解决方法

    Java项目导入IDEA的流程配置以及常见问题解决方法

    通常一个团队中可能有人用eclipse,有人用intelliJ,那么经常会出现需要导入别人用eclipse建好的web项目,下面这篇文章主要给大家介绍了关于Java项目导入IDEA的流程配置以及常见问题解决方法的相关资料,需要的朋友可以参考下
    2023-05-05
  • Spring Security OAuth2集成短信验证码登录以及第三方登录

    Spring Security OAuth2集成短信验证码登录以及第三方登录

    这篇文章主要介绍了Spring Security OAuth2集成短信验证码登录以及第三方登录,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • 查看SpringBoot和JDK版本对应关系的方法

    查看SpringBoot和JDK版本对应关系的方法

    在进行一些自主学习的时候,发现使用maven方式创建的SpringBoot项目启动失败,最终发现是SpringBoot版本和JDK版本不对应导致的,所以本文就给大家介绍了如何查看SpringBoot和JDK版本的对应关系,需要的朋友可以参考下
    2024-03-03
  • Springboot整合zookeeper实现对节点的创建、监听与判断的案例详解

    Springboot整合zookeeper实现对节点的创建、监听与判断的案例详解

    这篇文章主要介绍了基于Springboot整合zookeeper实现对节点的创建、监听与判断,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Java String初始化String域例题解析

    Java String初始化String域例题解析

    这篇文章主要介绍了Java String初始化String域例题解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10

最新评论