作为学习 J.U.C 包下的阻塞队列源码系列文章的开端,先简单的介绍 J.U.C 包下有哪些阻塞队列吧!
常用的阻塞队列 | 结构 | 是否有界 | 是否有锁 |
---|---|---|---|
ArrayBlockingQueue | 数组 | 有界 | 有锁 |
LinkedBlockingQueue | 链表 | 有界 | 有锁 |
LinkedBlockingDeque | 链表 | 有界 | 有锁 |
PriorityBlockingQueue | 数组的平衡二叉堆 | 有界 | 有锁 |
PriorityQueue | 数组的平衡二叉堆 | 有界 | 有锁 |
DelayQueue | 优先级队列 | 无界 | 有锁 |
SynchronousQueue | 队列或栈 | 无界 | 有锁 |
LinkedTransferQueue | 链表 | 无界 | 无锁 |
ConcurrentLinkedQueue | 链表 | 无界 | 无锁 |
以上的阻塞队列类除了 ConcurrentLinkedQueue 类之外,其余的阻塞队列都是通过实现 BlockingQueue 接口。可以说,BlockingQueue 接口是实现阻塞队列灵魂。既然这样,就先看看 BlockingQueue 接口类继承图是怎么样吧!
根据 BlockingQueue 类图就可以知道其实现类都具有哪些特性:
- 继承 Iterable:可以遍历阻塞队列
- 继承 Collection:可以操作集合相关的API
- 继承 Queue:该接口定义了操作队列的方法
- 继承 BlockingQueue:在 Queue 的基础上加上了阻塞的方法
接下来重点说一下 BlockingQueue 接口声明了哪些方法,都有哪些作用,这样有利于之后学习 BlockingQueue 实现类。
方法 | 操作 |
---|---|
add(E e) | 当队列满的时候会抛异常 |
offer(E e) | 当队列满的时候会返回 false |
offer(E e, long timeout, TimeUnit unit) | 当队列满的时候会阻塞,直到超时返回 false |
put(E e) | 当队列满的时候会阻塞 |
take() | 当队列为空的时候会阻塞 |
poll(long timeout, TimeUnit unit) | 当队列为空的时候会阻塞,直到超时返回 null |
remove(Object o) | 当队列为空的时候会抛异常(ps.LinkedBlockingQueue 实际是返回是 false) |
contains(Object o) | 如果队列当前没有对应的元素返回 false,反之返回 true |
简单来说,BlockingQueue 接口在 Queue 的继承上提供了一些阻塞方法,一直阻塞或者阻塞一段时间,这样在实际开发中可以更加灵活的使用阻塞队列。比如说一个请求过来,设置1秒内没有返回响应则返回其他页面,那么阻塞队列就可以设置超时时间,将无用的请求“丢掉”。
接下来,我将重点介绍几个常用的阻塞队列,包括 ArrayBlockingQueue
,LinkedBlockingQueue
,SynchronousQueue
,DelayQueue
,LinkedBlockingDeque
。相信通过这几篇文章的学习,会更加清楚阻塞队列的使用,更重要的是,线程池的实现直接应用到阻塞队列的API,而锁的实现也参考阻塞队列的思想实现了队列的操作;而对于学习消息队列框架也是有好处,因为很多底层原理都是队列,所以说,无论是对于基础或进阶来说过,学习阻塞队列的源码是很有必要,而且也是一名Java程序的基本功!
好了,废话不多说,开始学习阻塞队列源码吧!
下一篇为:J.U.C 阻塞队列源码剖析系列(二)之 ArrayBlockingQueue