多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代)

本文主要是介绍多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、LinkedBlockingDeque是什么

二、核心属性详解

三、核心方法详解

addFirst(E e)

offerFirst(E e)

putFirst(E e)

removeFirst()

pollFirst()

takeFirst()

其他

四、总结


一、LinkedBlockingDeque是什么

首先queue是一种数据结构,一个集合中,先进后出,有两种实现的方式,数组和链表。

从尾部追加,从头部获取。

Deque是两端都可以添加,且两端都可以获取,所以它的方法会有一系列的Last,Frist语义,添加或获取等操作

会指明哪个方向的,这也是Deque接口的定义。

那如果你不指定语义 如add()方法,他会默认调用addLast

综上所述,LinkedBlockingDeque是一个线程安全的双端阻塞队列。

二、核心属性详解

相对于LinkedBlockingQueue 他只能使用一把锁,不能分成put 和 take两把锁。

因为此时双端都可以put 和 take,所以只能使用一个锁,通过锁,对其链表实现线程安全的操作。

    //队列的头尾节点transient Node<E> first;transient Node<E> last;//队列中元素的数量private transient int count;//指定的队列的容量,默认Int最大值private final int capacity;//实现线程安全的使用的锁final ReentrantLock lock = new ReentrantLock();//获取元素的时候如果空了会使用它让其自己等待private final Condition notEmpty = lock.newCondition();//添加元素的时候如果满了(count == capacity)会使用它让其自己等待private final Condition notFull = lock.newCondition();

三、核心方法详解

下面会列举First系列的方法,因为last系列相对于first只是链表方向不一样,操作都是一致的。

addFirst(E e)

调用offerFirst 如果未成功 则抛出异常

    public void addFirst(E e) {if (!offerFirst(e))throw new IllegalStateException("Deque full");}

offerFirst(E e)

在链表的头部添加一个元素,使用ReentrantLock 保证线程安全

    public boolean offerFirst(E e) {if (e == null) throw new NullPointerException();Node<E> node = new Node<E>(e);//获取锁final ReentrantLock lock = this.lock;lock.lock();try {//把当前元素对应的节点放到头结点那里return linkFirst(node);} finally {lock.unlock();}}private boolean linkFirst(Node<E> node) {//如果元素已经超出容量,返回添加失败if (count >= capacity)return false;//链表的操作,用的是双向链表,first变成自己,之前的first是自己的nextNode<E> f = first;node.next = f;first = node;if (last == null)last = node;elsef.prev = node;//元素统计数量加1++count;//唤醒那些因为获取不到元素而阻塞的线程notEmpty.signal();return true;}

putFirst(E e)

相对于offer一个元素 如果元素数量已到达容量上线,会阻塞住等待元素被取走才放入

在juc下面 put add take等语义都是一致的

    public void putFirst(E e) throws InterruptedException {if (e == null) throw new NullPointerException();Node<E> node = new Node<E>(e);//获取锁final ReentrantLock lock = this.lock;lock.lock();try {//添加失败就阻塞住等待唤醒while (!linkFirst(node))notFull.await();} finally {lock.unlock();}}

removeFirst()

从头结点移除一个元素,调用的是pollFirst,拿出元素返回,元素==null会抛出异常

    public E removeFirst() {E x = pollFirst();if (x == null) throw new NoSuchElementException();return x;}

pollFirst()

取出first元素并返回,会返回null


    public E pollFirst() {//加锁final ReentrantLock lock = this.lock;lock.lock();try {// 取出first, 链表的操作和count的维护以及唤醒添加元素因为容量到达上线的等待的线程return unlinkFirst();} finally {lock.unlock();}}

takeFirst()

获取一个first元素,区别poll 在于会阻塞等待

    public E takeFirst() throws InterruptedException {final ReentrantLock lock = this.lock;//获取锁lock.lock();try {E x;//拿不到就阻塞等待,等待添加元素的时候被其他线程唤醒while ( (x = unlinkFirst()) == null)notEmpty.await();return x;} finally {lock.unlock();}}

其他

对于last系列方法,只是链表的操作方向不一样而已

其次默认的不带last 和 first系列的方法,即原始的add put等方法,可以等同LinkedBlockingQueue。

LinkedBlockingDeque内部是一个双向链表,支持了链表两端操作,所以方法不一一介绍,原理都是一样。

四、总结

LinkedBlockingDeque使用双端队列,通过ReentrantLock保证线程安全,实现了双端的线程安全的阻塞队列。

这篇关于多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148146

相关文章

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

linux安装、更新、卸载anaconda实践

《linux安装、更新、卸载anaconda实践》Anaconda是基于conda的科学计算环境,集成1400+包及依赖,安装需下载脚本、接受协议、设置路径、配置环境变量,更新与卸载通过conda命令... 目录随意找一个目录下载安装脚本检查许可证协议,ENTER就可以安装完毕之后激活anaconda安装更

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种