LinkedBlockingQueue原理探究

2024-01-09 19:52

本文主要是介绍LinkedBlockingQueue原理探究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

类图结构

同样首先看一下LinkedBlockingQueue的类图结构,以便从全局对LinkedBlockingQueue有个直观的了解。

在这里插入图片描述
由类图可以看到,LinkedBlockingQueue也是使用单向链表实现的,其也有两个Node,分别用来存放首、尾节点,并且还有一个初始值为0的原子变量count,用来记录队列元素个数。

另外还有两个ReentrantLock的实例,分别用来控制元素入队和出队的原子性,其中takeLock用来控制同时只有一个线程可以从队列头获取元素,其他线程必须等待,putLock控制同时只能有一个线程可以获取锁,在队列尾部添加元素,其他线程必须等待。

另外,notEmpty和notFull是条件变量,它们内部都有一个条件队列用来存放进队和出队时被阻塞的线程,其实这是生产者—消费者模型。

在这里插入图片描述

  • 当调用线程在LinkedBlockingQueue实例上执行take、poll等操作时需要获取到takeLock锁,从而保证同时只有一个线程可以操作链表头节点。

    另外由于条件变量notEmpty内部的条件队列的维护使用的是takeLock的锁状态管理机制,所以在调用notEmpty的await和signal方法前调用线程必须先获取到takeLock锁,否则会抛出IllegalMonitorStateException异常。

    notEmpty内部则维护着一个条件队列,当线程获取到takeLock锁后调用notEmpty的await方法时,调用线程会被阻塞,然后该线程会被放到notEmpty内部的条件队列进行等待,直到有线程调用了notEmpty的signal方法。

  • 在LinkedBlockingQueue实例上执行put、offer等操作时需要获取到putLock锁,从而保证同时只有一个线程可以操作链表尾节点。

    同样由于条件变量notFull内部的条件队列的维护使用的是putLock的锁状态管理机制,所以在调用notFull的await和signal方法前调用线程必须先获取到putLock锁,否则会抛出IllegalMonitorStateException异常。

    notFull内部则维护着一个条件队列,当线程获取到putLock锁后调用notFull的await方法时,调用线程会被阻塞,然后该线程会被放到notFull内部的条件队列进行等待,直到有线程调用了notFull的signal方法。

在这里插入图片描述
默认队列容量为0x7fmf,用户也可以自己指定容量,所以从一定程度上可以说LinkedBlockingQueue是有界阻塞队列。

LinkedBlockingQueue原理介绍

offer操作

向队列尾部插入一个元素,如果队列中有空闲则插入成功后返回true,如果队列已满则丢弃当前元素然后返回false。

如果e元素为null则抛出NullPointerException异常。另外,该方法是非阻塞的。

在这里插入图片描述
在这里插入图片描述

put操作

向队列尾部插入一个元素,如果队列中有空闲则插入后直接返回,如果队列已满则阻塞当前线程,直到队列有空闲插入成功后返回。

如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出InterruptedException异常而返回。

另外,如果e元素为null则抛出NullPointerException异常。

在这里插入图片描述

poll操作

从队列头部获取并移除一个元素,如果队列为空则返回null,该方法是不阻塞的。
在这里插入图片描述
在这里插入图片描述

peek操作

获取队列头部元素但是不从队列里面移除它,如果队列为空则返回null。该方法是不阻塞的。
在这里插入图片描述

take操作

获取当前队列头部元素并从队列里面移除它。

如果队列为空则阻塞当前线程直到队列不为空然后返回元素,如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出InterruptedException异常而返回。

在这里插入图片描述

remove操作

删除队列里面指定的元素,有则删除并返回true,没有则返回false。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

size操作

获取当前队列元素个数。

在这里插入图片描述
在这里插入图片描述

这篇关于LinkedBlockingQueue原理探究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit