java-阻塞队列之LinkedBlockingQueue

1|0概述

LinkedBlockingQueue内部由单链表实现,只能从head取元素,从tail添加元素。添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行。LinkedBlockingQueue采用可重入锁ReentrantLock来保证在并发情况下的线程安全。

2|0构造器

LinkedBlockingQueue一共有三个构造器,分别是无参构造器、可以指定容量的构造器、可以穿入一个容器的构造器。如果在创建实例的时候调用的是无参构造器,LinkedBlockingQueue的默认容量是Integer.MAX_VALUE,这样做很可能会导致队列还没有满,但是内存却已经满了的情况(内存溢出)。

public LinkedBlockingQueue(); //设置容量为Integer.MAX public LinkedBlockingQueue(int capacity); //设置指定容量 public LinkedBlockingQueue(Collection<? extends E> c); //穿入一个容器,如果调用该构造器,容量默认也是Integer.MAX_VALUE

3|0LinkedBlockingQueue常用操作

3|1取数据

take():首选。当队列为空时阻塞

poll():弹出队顶元素,队列为空时,返回空

peek():和poll烈性,返回队队顶元素,但顶元素不弹出。队列为空时返回null

remove(Object o):移除某个元素,队列为空时抛出异常。成功移除返回true

3|2添加数据

put():首选。队满是阻塞

offer():队满时返回false

3|3判断队列是否为空

size()方法会遍历整个队列,时间复杂度为O(n),所以最好选用isEmtpy

4|0put元素原理

基本过程:

1.判断元素是否为null,为null抛出异常

2.加锁(可中断锁)

3.判断队列长度是否到达容量,如果到达一直等待

4.如果没有队满,enqueue()在队尾加入元素

5.队列长度加1,此时如果队列还没有满,调用signal唤醒其他堵塞队列

if (e == null) throw new NullPointerException(); int c = -1; Node<E> node = new Node<E>(e); final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; putLock.lockInterruptibly(); try { while (count.get() == capacity) { notFull.await(); } enqueue(node); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); } finally { putLock.unlock(); }

5|0take元素原理

基本过程:

1.加锁(依旧是ReentrantLock),注意这里的锁和写入是不同的两把锁

2.判断队列是否为空,如果为空就一直等待

3.通过dequeue方法取得数据

3.取走元素后队列是否为空,如果不为空唤醒其他等待中的队列

public E take() throws InterruptedException { E x; int c = -1; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { while (count.get() == 0) { notEmpty.await(); } x = dequeue(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); } finally { takeLock.unlock(); } if (c == capacity) signalNotFull(); return x; }

enqueue()和dequeue()方法实现都比较简单,无非就是将元素添加到队尾,从队顶取走元素,感兴趣的朋友可以自己去看一下,这里就不粘贴了。


__EOF__

本文作者😎
本文链接https://www.cnblogs.com/dongye95/p/16043035.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   dongye95  阅读(165)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示