一、阻塞队列介绍
学过java或者数据结构的同学应该都清除队列的概念,当队列和阻塞混在一起之后会是一种什么样呢?
阻塞队列如下特点:
- 当队列为空时,从队列中取元素的操作阻塞
- 当队列慢时,向队列中添加元素的操作阻塞
二、用途
1、用途
- 生产者消费者,在没有阻塞队列之前,我们实现生产者消费者是使用同步synchonized、wait、notify去操作线程
- 一些消息中间件的核心
三、阻塞队列类型
| 队列 | 有界性 | 锁 | 数据结构 |
|---|---|---|---|
| ArrayBlockingQueue | bounded(有界) | 加锁 | arrayList |
| LinkedBlockingQueue | optionally-bounded | 加锁 | linkedList |
| PriorityBlockingQueue | unbounded | 加锁 | heap |
| DelayQueue | unbounded | 加锁 | heap |
| SynchronousQueue | bounded | 加锁 | 无 |
| LinkedTransferQueue | unbounded | 加锁 | heap |
| LinkedBlockingDeque | unbounded | 无锁 | heap |
重点介绍ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue这三个队列,这三个在线程池中有使用到。
- ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序
- LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序
- SynchronousQueue: 一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。
四、特殊的API
| 方法\处理方式 | 抛出异常 | 返回特殊值 | 一直阻塞 | 超时退出 |
|---|---|---|---|---|
| 插入方法 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
| 移除方法 | remove() | poll() | take() | poll(time,unit) |
| 检查方法 | element() | peek() | 不可用 | 不可用 |
- 抛出异常:插入操作时,队列满抛出“队列满”异常;移除操作时,队列空时抛出“没有元素”异常
- 返回特殊值:插入操作时,成功返回true,失败返回false。移除操作时,成功时返回移除的元素,失败时返回false
- 一直阻塞:插入操作时,队列满,方法阻塞;移除操作时,队列空时,方法阻塞。
- 超时退出:在一直阻塞的情况下,加一个超时时间。