当我们要创建ThreadPoolExecutor的时候需要传进来一个类型为BlockingQueue的参数,它就是阻塞队列,在这一篇文章里我们会介绍阻塞队列的定义、种类、实现原理以及应用。
阻塞队列,是一个队列,而在一个阻塞队列在数据结构中所起的作用大致如下图所示
当阻塞队列是空时,从队列中获取元素的操作将会被阻塞
当阻塞队列时满时,往队列里添加元素的操作将会被阻塞
阻塞队列有什么好处
在多线程领域:所谓阻塞,在某些情况下,会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤醒
ArrayBlockingQueue:由数狙结构組成的有界阻塞队列。
LinkedBlockingQueue:由链表构狙成的有界(但大小默人値カInteger.MAX_ _VALUE)阻塞队列
SynchronousQueue:不存储元素的阻塞队列,也即単个元素的队列
PriorityBlockingQueue:支持优先级排序的无界阻塞叺列
DelayQueue:使用优先级队列实现的延迟无界阻塞臥列
linkedTransferQueue:由链表结构組成的无界阻塞队列
LinkedBlockingDeque:由链表结构組成的双向阻塞队列
阻塞队列提供了四种处理方法:
方法类型 | 抛出异常 | 特殊值 | 阻塞 | 超时 |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除 | remove() | poll() | take() | poll(time,unit) |
检查 | element() | peek() | 不可用 | 不可用 |
- 抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出 IllegalStateException(“Queue full”) 异常。当队列为空时,从队列里获取元素时会抛出 NoSuchElementException 异常 。
- 返回特殊值:插入方法会返回是否成功,成功则返回 true。移除方法,则是从队列里拿出一个元素,如果没有则返回 null
- 一直阻塞:当阻塞队列满时,如果生产者线程往队列里 put 元素,队列会一直阻塞生产者线程,直到拿到数据,或者响应中断退出。当队列空时,消费者线程试图从队列里 take 元素,队列也会阻塞消费者线程,直到队列可用。
- 超时退出:当阻塞队列满时,队列会阻塞生产者线程一段时间,如果超过一定的时间,生产者线程就会退出。
线程通信之生产者消费者阻塞队列
1 | import java.util.concurrent.ArrayBlockingQueue; |