BlockingQueue
1、BlockingQueue类的结构
2、继承关系
public interface BlockingQueue<E> extends Queue<E>
BlockingQueue继承自Queue接口,在此基础上增加了阻塞操作,可以支持两个附加操作:
- 支持阻塞的加入方法:在队列满的时候添加元素会被阻塞,直至队列可以添加成功才返回(put());
- 支持阻塞的移除方法:在队列为空时,删除元素的线程会被阻塞,直至队列中有元素可以被删除时成功返回(take());
3、应用场景:阻塞队列常用于生产者消费者的场景中,生产者是向队列中添加元素的过程,消费者是从队列里取元素的过程,阻塞队列是生产者用来存放元素、消费者用来获取元素的容器;
4、提供的方法
方法/处理方式 | 抛出异常 | 返回特殊值 | 阻塞 | 超时退出 |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
移除 | remove() | poll() | take() | poll(time, unit) |
检查 | element() | peek() | 不可用 | 不可用 |
1)抛出异常:
- 当队列满时,如果再往队列里插入元素,会抛出IllegalStateException(“Queue
full”)异常; - 当队列空时,从队列里获取元素会抛出NoSuchElementException异常;
2)返回特殊值:
- 当往队列插入元素时,会返回元素是否插入成功,成功返回true;
- 如果是移除方法,则是从队列里取出一个元素,如果没有则返回null;
3)阻塞:
- 当阻塞队列满时,如果生产者线程往队列里put元素,队列会一直阻塞生产者线程,直到队列可用或者响应中断退出;
- 当队列空时,如果消费者线程从队列里take元素,队列会阻塞住消费者线程,直到队列不为空;
4)超时退出:
- 当阻塞队列满时,如果生产者线程往队列里插入元素,队列会阻塞生产者线程一段时间,如果超过了指定的时间,生产者线程就会退出。
注意 :如果是无界阻塞队列,队列不可能会出现满的情况:
- 使用put或offer方法永远不会被阻塞;
- 使用offer方法时,该方法永远返回true;
5、Java中提供了7个阻塞队列
1)ArrayBlockingQueue:由数组结构组成的有界阻塞队列;
2)LinkedBlockingQueue:由链表结构组成的有界阻塞队列;
3)PriorityBlockingQueue:支持优先级排序的无界阻塞队列;
4)DelayQueue:使用优先级队列实现的无界阻塞队列;
5)SynchronousQueue:同步阻塞队列,不存储元素;
6)LinkedTransferQueue:由链表结构组成的无界阻塞队列;
7)LinkedBlockingDeque:由链表结构组成的双向阻塞队列;
6、阻塞队列使用了通知模式来实现
通知模式,就是当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用。例如ArrayBlockingQueue使用了Condition来实现。