Collection - Queue队列

本文详细介绍了Java中的BlockingQueue接口及其常见实现,包括LinkedTransferQueue、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、SynchronousQueue和PriorityBlockingQueue。 BlockingQueue提供了一组线程安全的队列操作,适用于消费者与生产者场景。各队列特性各异,如LinkedTransferQueue支持立即消费,ArrayBlockingQueue是定长有界的,DelayQueue允许延迟取出,SynchronousQueue则是一对一的同步传递,而PriorityBlockingQueue则支持自定义排序规则。
摘要由CSDN通过智能技术生成

目录

知识体系

BlockingQueue

TransferQueue

LinkedTransferQueue

ArrayBlockingQueue

DelayQueue

LinkedBlockingQueue

SnychronousQueue

PriorityBlockingQueue

总结


知识体系

BlockingQueue

添加方法:

boolean add(E e)、boolean offer() 、void put()、boolean offer(E e,long time,Timeunit timeunit)

取值方法:

take()、poll(long time,TimeUnit timeunit)

其他方法:

int remainingCapacity():获取剩余队列的空间大小

boolean remove(Object o):删除指定元素

boolean contains():判断队列是否有改元素

int drainTo(Collection c):批量获取队列中的值并全部移除

int drainTo(Collection c,int maxElements):批量获取队列中指定顺序的值并全部移除

BlockingQueue为消费者与服务者的使用场景提供了基础的方法,可以根据业务场景的需要选择合适的Queue和方法进行开发

TransferQueue

TransferQueue是一个立即消费的队列

void transfer(E e):若当前存在一个正在等待消费的线程,会立刻将e元素转移给消费线程,否则进入队列尾部,阻塞线程,直到有线程消费该元素

boolean tryTransfer(E e):若当前存在一个正在等待消费的线程,会立刻将e元素转移给消费者,否则不会进入队列,返回false

boolean tryTransfer(E e,long timeout,TimeUnit timeunit):如果当前存在一个正在等待消费的线程,会立刻将e元素转移给消费者,否则,在指定时间内没有消费,该元素不会进入队列,返回false

hasWaitingConsumer():判断是否存在消费者线程

getWaitingConsumerCount():获取等待消费者线程个数

LinkedTransferQueue

LinkedTransferQueue的使用具体可参考地址:

https://blog.csdn.net/jurson99/article/details/53422266

ArrayBlockingQueue

ArrayBlockingQueue底层是数据实现的定长的有界队列,有用到ReentrantLock,所以是线程安全的

构造函数:

// 必须指定容量大小,默认是非公平锁的队列
public ArrayBlockingQueue(int capacity){  this(capacity,false)  }

//自定义容量,是否公平锁
public ArrayBlockingQueue(int capacity,booean fair)

//自定义容量,是否公平锁,最初包含的元素集合
public ArrayBlockingQueue(int capacity,boolean fair, Cllocetion c)

添加方法:

方法名称

元素插入队列流程

队列没有多余空间时返回值

add(E e)

将元素插入队列尾部

抛出异常"Queue full"

boolean

put(E e)

判断元素是否为空,为空报空指针异常,线程可被中断,中断的线程会抛异常,当数组容量满时,while循环等待通知数组容量释放空间,否则正常执行将元素插入items

可中断线程或等待空间可用,Condition await / signal(等待 / 通知),(所有线程数据都会被执行)

void

offer(E e)

判断元素是否为空,为空时报空指针异常,应用互斥锁,阻塞线程,如果数组容量满时,返回false,否则将元素插入items,返回true,最后释放锁

阻塞队列,返回false

boolean

offer(E e,long time,TimeUnit unit)

判断元素是否为空,为空时报空指针异常,线程可被中断,中断的线程会抛异常,当数组容量满时,在指定时间内数组容量依然满时,返回false,否则正常执行添加到items

在指定时间添加元素,超过时间返回false

boolean

取值方法:

取值方法

元素插入队列流程

空值取值处理方式

返回结果

peek()

应用互斥锁阻塞线程,取出第一个数组元素,没有元素返回null值

null

E

take()

应用互斥锁阻塞线程,等待的线程可被中断,当数组为0时while循环等待,否则正常消费

null

E

poll()

应用互斥锁阻塞线程,当数组容量为0时返回null值,否则正常消费

null

E

poll(long timeout,TimeUnit unit)

应用互斥锁阻塞线程,等待的线程可被中断,当数组为0时,在指定时间数组容量依然是0时,返回null值,否则正常消费

在指定时间没获取到值,返回null

E

ArrayBlockingQueue的使用参考:

https://blog.csdn.net/u014082714/article/details/5221513

DelayQueue

DelayQueue是一种延迟队列,插入的元素可以按照自定义的时间进行排序, 只有getDelay()方法中的返回值小于或等于0才会被消费线程取出

具体参考:

https://www.jianshu.com/p/bf9f6b08ba5b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

https://zhuanlan.zhihu.com/p/279515674

LinkedBlockingQueue

 LinkedBlockingQueue 是基于单向链表实现的队列,内部方法的使用跟ArrayBlockingQueue差不多,很多人说LinkedBlockingQueue是无界队列,实际来说还是有界队列,默认最大值Integer.maxValue = 2147483647,21亿多

//默认最大值是Integer.maxValue:21亿
public LinkedBlockingQueue(){ this (Integer.maxValue)} 

//自定义容量大小
public LinkedBlockingQueue(int capacity)

//指定初始元素的集合
public LinkedBlockingQueue(Cllection c)

LinkedBlockingQueue的使用参考:

https://blog.csdn.net/evankaka/article/details/51706109

做一下与ArrayBlockingQueue与LinkedBlockingQueue的对比:

1、ArrayListBlockingQueue是将数据放在数组中,二LinkedBlockingQueue是将数据放到Node节点链表中

2、ArrayListBlockingQueue获取数据与取得数据都是同一把锁,二LinkedBlockingQueue有两把锁,一把放入锁,一把取出锁,分别对应元素的放入与取出,而删除元素要同时取得两把锁

SnychronousQueue

SnychronousQueue是一个同步队列,生产者每生产一个元素,如果没有被消费者消费,下一个元素会被阻塞,否则被消费,是一个一对一的关系,没有容量来存储多个元素

参考文章:

https://blog.csdn.net/zmx729618/article/details/52980158/

PriorityBlockingQueue

PriorityBlockingQueue是一个优先级队列,可以自定义排序规则,决定元素的出队顺序

参考文章:

https://blog.csdn.net/LO_YUN/article/details/106057352

https://blog.csdn.net/qq_22701869/article/details/107146519

总结

队列名称有界/无界队列简单概述
ArrayBlockingQueue有界必须指定长度,有公平与非公平锁之分
LinkedBlockingQueue有界默认大小Integer.maxValue = 2147483647,可以自定义容量大小
SynchronousQueue 有界容量为0
PriorityBlockingQueue无界

put操作不会阻塞,限制来源与系统资源大小

底层使用CAS无锁编程

底层扩容:

默认容量大小为11,扩容机制:如果容量小于64,只会在原有的基础上加2,否则新容量是旧容量的1.5倍

LinkedTransferQueue 无界存在消费者线程会立即消费,否则根据调用方法不同,该元素是否入队或者直接出队返回false
DelayQueue无界底层是用优先级队列实现的,扩容机制跟PriorityBlockingQueue一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值