阻塞队列
说到多线程,就一定绕不开阻塞队列,本文就阻塞队列的共性与不同进行分析归纳
队列基础方法分析
所有的阻塞队列都实现了BlockingQueue接口,那我们就首先来看看BlockingQueue接口都有哪些方法
如上图所示,每一个阻塞队列都应该拥有上述方法,接下来我们针对不同的情况来对各类方法进行分析
对于添加而言,分为如下几类情况
- 添加成功
- 待添加元素不允许被添加到这个阻塞队列
- 阻塞队列空间已满
对于第一种情况,三种添加的表现都是一致的,会返回true
对于第二种情况,三种添加的表现也是一致的,会抛出IllegalArgumentExecption
对于第三种情况,add方法会抛出IllegalStateException,offer方法会返回false,put方法则会一直等待,直到有空间可以使待添加元素被添加
对于删除的四个方法,其实各有不同,并不是对某些情况的不同处理。
- take方法会从队列中拿出头元素返回,如果队列为空会一直等待
- poll方法与take方法同理,但是会有一个等待时间,如果在这段等待时间内没有取到则会返回null
- remove方法则会从队列中找出第一个符合equals方法的元素并将其删除而后返回true,如果没找到则返回false
- drainTo则会将所有元素都装入入参的集合中返回
对于查看的四个方法,我们说一下element和peek
如果我们想要获取队列中的元素却不想删除它怎么办呢?就可以用element和peek了,这两个方法的区别就在于当队列为空时,element会抛出异常,peek会返回false
阻塞队列分类
上一节中我们讨论了阻塞队列中的方法,在本节中我们对阻塞队列接口的实现类进行分类分析,在ThreadPoolExecutor的源码注释中将阻塞队列分成了三种
直接交付(SynchronousQueue)
不排队,直接新建线程来执行
无界队列
LinkedBlockingQueue
实现方式:链表。队列永远不会满,此时核心线程数可以和最大线程数一样
PriorityBlockingQueue
实现方式:可扩容的数组。优先级阻塞队列,要求被添加元素要实现Camparable接口
DelayQueue
实现方式:可扩容的数组。延时队列,要求被添加的元素要实现Delay接口
有界队列(ArrayBlockingQueue)
初始化时指定数量