LinkedBlockingQueue的源码解析(基于JDK1.8)

简介: LinkedBlockingQueue的源码解析(基于JDK1.8)LinkedBlockingQueue是Java集合框架中的一个阻塞队列实现类,它是线程安全的,支持高并发操作。本文将对LinkedBlockingQueue的源码进行解析,基于JDK1.8版本。

LinkedBlockingQueue的源码解析(基于JDK1.8)

LinkedBlockingQueue是Java集合框架中的一个阻塞队列实现类,它是线程安全的,支持高并发操作。本文将对LinkedBlockingQueue的源码进行解析,基于JDK1.8版本。

基本介绍

LinkedBlockingQueue是一个基于链表实现的阻塞队列,它具有以下特点:

队列容量可选,默认为Integer.MAX_VALUE。

链表节点有一个前驱节点和一个后继节点,可以快速的添加、删除、检索元素。

队列支持两种模式:公平模式和非公平模式。在公平模式下,线程按照FIFO顺序竞争访问队列;在非公平模式下,线程可以随意竞争访问队列。

阻塞队列支持put()和take()方法,分别用于添加元素和获取元素。当队列满时,put()方法会阻塞等待;当队列空时,take()方法会阻塞等待。

源码解析

变量定义

LinkedBlockingQueue的源码定义了以下变量:

transient Node<E> first;
transient Node<E> last;
private final int capacity;
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();

其中,first和last分别表示链表的头结点和尾节点;capacity表示队列容量;takeLock和putLock则是两个ReentrantLock类型的锁,用于控制take()和put()方法的并发访问。notEmpty和notFull则是两个Condition类型的条件变量,用于控制阻塞等待的线程。

节点定义

LinkedBlockingQueue的节点定义如下:

static class Node<E> {
    E item;
    Node<E> next;
    Node(E x) { item = x; }
}

节点包含一个元素和一个指向下一个节点的指针。每个节点都是一个独立的实体,可以单独进行操作,例如添加、删除、检索等。

添加元素

LinkedBlockingQueue的add()方法用于向队列中添加元素,源码如下:

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

add()方法内部调用了offer()方法,如果offer()方法返回true,则表示添加成功,直接返回true;如果offer()方法返回false,则表示队列已满,抛出IllegalStateException异常。

offer()方法的源码如下:

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    final ReentrantLock putLock = this.putLock;
    putLock.lock();
    try {
        while (count == capacity) {
            notFull.await();
        }
        insert(e);
        return true;
    } finally {
        putLock.unlock();
    }
}

offer()方法首先获取putLock锁,然后判断队列是否已满。如果队列已满,则将当前线程阻塞在notFull条件变量上,等待其他线程从队列中取出元素,以便腾出空间。insert()方法用于将元素添加到队列尾部。最后,释放putLock锁。

获取元素

LinkedBlockingQueue的take()方法用于从队列中获取元素,源码如下:

public E take() throws InterruptedException {
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lockInterruptibly();
    try {
        while (count == 0) {
            notEmpty.await();
        }
        return extract();
    } finally {
        takeLock.unlock();
    }
}

take()方法首先获取takeLock锁,然后判断队列是否为空。如果队列为空,则将当前线程阻塞在notEmpty条件变量上,等待其他线程向队列中添加元素。extract()方法用于从队列头部获取元素。最后,释放takeLock锁。

总结

LinkedBlockingQueue是一个高性能、线程安全的阻塞队列实现类,它的源码实现了链表节点的添加、删除、检索等基本操作。在多线程并发访问时,它使用了ReentrantLock和Condition等线程同步机制,保证了线程安全性和高并发性能。

相关文章
|
3月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
302 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
8月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
816 29
|
8月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
322 4
|
8月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
|
8月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
4月前
|
存储 Ubuntu 安全
在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
在整个安装过程中,你可能需要管理员权限,因此你可能要使用 `sudo` 来获取必要的权限。记得做完每一个步骤后,都要检查输出,以确保没有发生错误,并且每项操作都成功完成。如果在安装过程中遇到问题,查看 `/var/log/` 下的日志文件对于问题的解决可能是有帮助的。
315 21
|
4月前
|
IDE Ubuntu Java
在Ubuntu18.04安装兼容JDK 8的Eclipse集成开发环境的指南。
完成以上步骤后,您将在Ubuntu 18.04系统上成功安装并配置了Eclipse IDE,它将与JDK 8兼容,可以开始进行Java开发工作。如果遇到任何问题,请确保每一步骤都正确执行,并检查是否所有路径都与您的具体情况相匹配。
209 11
|
3月前
|
Ubuntu Java Android开发
在Ubuntu 18.04上安装与JDK 8兼容的Eclipse版本的步骤。
安装过程结束后,您就可以开始使用Eclipse来开发您的Java项目了,并且确保它与JDK 8兼容无误。这个过程涉及的是一个基本的安装流程,针对使用Java 8的用户,Eclipse的其他配置和插件安装根据个人开发环境和需求来定制。
300 0
|
6月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
384 41

推荐镜像

更多
  • DNS