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;
    }

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

总结

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

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

相关文章

  • Spring Cloud使用Feign进行远程调用的操作指南

    Spring Cloud使用Feign进行远程调用的操作指南

    本文介绍了Feign作为声明式HTTP客户端在SpringCloud中的使用,从简介、对比RestTemplate的问题、使用步骤,到日志配置、性能优化和实际应用进行了详细讲解,包括如何通过Feign简化接口调用,以及解决启动时找不到FeignClient的问题,需要的朋友可以参考下
    2025-02-02
  • Java关键字final的实现原理分析

    Java关键字final的实现原理分析

    这篇文章主要介绍了Java关键字final的实现原理分析,在JDK8之前,如果在匿名内部类中需要访问局部变量,那么这个局部变量一定是final修饰的,但final关键字可以省略,需要的朋友可以参考下
    2024-01-01
  • application.yml文件中如何开启mybatis自动驼峰映射

    application.yml文件中如何开启mybatis自动驼峰映射

    这篇文章主要介绍了application.yml文件中开启mybatis自动驼峰映射的方法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Java实现大文件的分片上传与下载(springboot+vue3)

    Java实现大文件的分片上传与下载(springboot+vue3)

    这篇文章主要为大家详细介绍了java基于springboot+vue3如何大文件的分片上传与下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2023-06-06
  • tio-boot jfinal-plugins框架整合redis示例详解

    tio-boot jfinal-plugins框架整合redis示例详解

    这篇文章主要为大家介绍了tio-boot jfinal-plugins框架整合redis示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • java实现仿射密码加密解密

    java实现仿射密码加密解密

    这篇文章主要为大家详细介绍了java实现仿射密码加密解密的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Java 数据结构与算法系列精讲之单向链表

    Java 数据结构与算法系列精讲之单向链表

    单向链表特点是链表的链接方向是单向的,访问要通过顺序读取从头部开始。链表是使用指针构造的列表,是由一个个结点组装起来的,又称为结点列表。其中每个结点都有指针成员变量指向列表中的下一个结点,head指针指向第一个结点称为表头,而终止于最后一个指向nuLL的指针
    2022-02-02
  • 详解JAVA 时间处理相关类

    详解JAVA 时间处理相关类

    这篇文章主要介绍了JAVA 时间处理相关类的知识,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 基于Java方式实现数据同步

    基于Java方式实现数据同步

    这篇文章主要为大家详细介绍了基于Java方式实现数据同步,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • java线程Thread.sleep()对比对象的wait示例解析

    java线程Thread.sleep()对比对象的wait示例解析

    这篇文章主要为大家介绍了java线程Thread.sleep()对比对象的wait示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论