目录
知识体系
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://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一样 |