千家信息网

如何进行阻塞队列LinkedBlockingQueue源码学习与对比

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家介绍如何进行阻塞队列LinkedBlockingQueue源码学习与对比,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。今天学习LinkedBlockingQueue
千家信息网最后更新 2026年11月02日如何进行阻塞队列LinkedBlockingQueue源码学习与对比

这篇文章给大家介绍如何进行阻塞队列LinkedBlockingQueue源码学习与对比,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

今天学习LinkedBlockingQueue源码并与之对比。

LinkedBlockingQueue总结

同样先直接总结LinkedBlockingQueue相关的特性,再根据源码来进行说明,它的主要特性如下:

1、他底层用链表实现数据存储;

2、他是一个FIFO无界阻塞队列。数据最大长度默认Intenger的最大值Integer.MAX_VALUE,也可以设置长度;

重要属性介绍

主要属性如下图:

LinkedBlockingQueue有一个内部类Node,用来组成它存储数据的链表,Node的item数据用来存储数据,next表示下一个节点,尾节点的next是null。

capacity容量表示队列最多可存储的数据量,初始化的时候设置,默认是Integer.MAX_VALUE;

count表示当前存储数据的数量,它是AtomicInteger类型(可以想想为什么?);

head链表的头节点,它的item不存放数据;

tail链表的尾节点,它的next为null,也就是没有下一个节点;

takeLock与notEmpty控制take方法的阻塞;

putLock与notFull控制put方法的阻塞;

从上面属性可以猜出来LinkedBlockingQueue是用两个锁来控制数据的读和写,相当于把读和写分开,可以同时存在读和写操作,所以count有可能同时存在多个线程修改,有线程安全问题所以用AtomicInteger。

最关键的两个私有方法

同样LinkedBlockingQueue也有两个相同的关键方法,具体代码和解释如下图:

LinkedBlockingQueue的enqueue和dequeue方法比ArrayBlockingQueue的更加简单;

enqueue方法就是把新的节点放到last的next,然后把节点设置成尾节点。

dequeue是先拿到头节点next节点作为first节点,然后之前的头节点就的next设置成了自己,就脱离了链表,下次GC就会被回收掉。

然后first就作为head,把item拿出来后设置为null,所以头节点是不存储数据的,并且是由下一个节点升级来的。

LinkedBlockingQueue的这两个方法比较简单,但是也可以看出它实现了FIFO先进先出。

主要方法介绍

LinkedBlockingQueue与ArrayBlockingQueue一样都是继承至 AbstractQueue并实现 BlockingQueue接口,所以他们提供的方法都差不多,功能也类似,主要实现不同,上一篇已经详细讲了,这里就只看一下take和put方法的实现。

put方法源码如下图:

一共分四步:

把数据封装成Node节点,获取put锁;

验证队列是否已满,满则阻塞线程;

如果没有满则把节点加到队列中,count加1,并获取加之前的数量;

如果现在数量还是小于最大容量则唤醒阻塞的put线程,如果之前数量是0则唤醒take线程;

take方法源码如下图:

take方法和put方法差不多,主要分以下四步:

首先获取take锁;

判断队列中是否有数据,如果没有则阻塞线程;

调用dequeue方法获取数据,并把count减1;

如果获取前队列数量大于1则说明还有数据,可以唤醒其他take线程,如果获取前队列数量等于最大容器数量则说明有可能有阻塞的put线程,需要唤醒;

可以看到put和take方法很简单,都是先获取到对于的锁,然后根据队列数量判断是否阻塞,然后再添加或者获取数据,最后根据唤醒对应线程;

与ArrayBlockingQueue对比(重点)

LinkedBlockingQueue与ArrayBlockingQueue是非常相似的类,通过对比能够更体现他们的优缺点,主要对比如下:

从基础属性对比LinkedBlockingQueue底层实现是链表,ArrayBlockingQueue是数组。ArrayBlockingQueue初始化需要一个数组,而LinkedBlockingQueue是动态数量的Node对象;所以ArrayBlockingQueue需要预先分配内存,而LinkedBlockingQueue不用,如果预计需要缓存的数据很多的,那么ArrayBlockingQueue一开始就需要很大一块数据。

但是ArrayBlockingQueue添加元素更快,因为它只是要要保存的对象的引用放到数组对应位置,而LinkedBlockingQueue需要创建一个Node对象;同时在获取后这个Node对象变成了垃圾,在读写很大的情况会多出很多垃圾,可能会影响程序的性能;

ArrayBlockingQueue用一个锁控制读写,LinkedBlockingQueue用两个锁分别控制读写。因为ArrayBlockingQueue为了避免数据被覆盖,而LinkedBlockingQueue不用担心这种情况,可以同时支持读写,而ArrayBlockingQueue同一时刻支持一个操作,所以LinkedBlockingQueue吞吐量更高。

所以ArrayBlockingQueue会占用固定的内存,所以不能支持太大的缓存,但是每次操作延迟更加低,而LinkedBlockingQueue不用暂用一个初始化的内存,但是每次操作消耗的内存更大,不过同时支持读写所以吞吐量更高。

但是在使用LinkedBlockingQueue时,如果使用默认大小且当生产速度大于消费速度时候,有可能会内存溢出。

LinkedBlockingQueue与ArrayBlockingQueue提供的功能完全相同,但是他们底层的实现不同,所以侧重点不同,在使用中可以根据情况选择。

关于如何进行阻塞队列LinkedBlockingQueue源码学习与对比就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

数据 方法 节点 队列 阻塞 数量 线程 源码 存储 两个 内存 同时 控制 最大 对象 属性 支持 学习 不同 不用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中关村互联网 科技集团 江苏根荣互联网科技 互联网科技公司的优势 狮子座互联网科技 互联网与新科技 安徽鑫晟辉互联网科技 互联网 视角下的科技创新 互联网科技公司名称 中国互联网金融科技基金 互联网科技如何创业 工业互联网展湾科技股份有限公司 北京市互联网新科技 易企秀互联网科技是做什么的 互联网科技包装股 济南小医互联网科技有限公司招聘 张家口科技产业互联网平台 马化腾互联网科技教学 唐山双旺合互联网科技产业园 平安好医生打造互联网科技医疗 恒生互联网科技趋势 互联网科技卖菜 睿民互联网科技 互联网公司会议桌创意科技软装饰 互联网科技有哪些公司 南平创想时代互联网科技有限公司 保险科技服务互联网营销体系 互联网科技圈年度人物 云南省自由互联网科技有限公司 厦门江牛科技互联网 张家口科技产业互联网平台
0