BlockingQueue简介
BlockingQueue
是在JDK1.5时,随着J.U.C引入的一个接口:
public interface BlockingQueue<E> extends Queue<E> {
}
BlockingQueue继承了Queue接口,提供了一些阻塞方法,主要作用如下:
- 当线程向队列中插入元素时,如果队列已满,则阻塞线程,直到队列有空闲位置(非满);
- 当线程从队列中取元素(删除队列元素)时,如果队列为空,则阻塞线程,直到队列有元素;
既然BlockingQueue是一种队列,所以也具备队列的三种基本方法:插入、删除、读取:
操作类型 | 抛出异常 | 返回特殊值 | 阻塞线程 | 超时 |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
删除 | remove() | poll() | take() | poll(time, unit) |
读取 | element() | peek() | / | / |
可以看到,对于每种基本方法,“抛出异常”和“返回特殊值”的方法定义和Queue是完全一样的。BlockingQueue只是增加了两类和阻塞相关的方法:put(e)
、take()
;offer(e, time, unit)
、poll(time, unit)
。
put(e)和take()方法会一直阻塞调用线程,直到线程被中断或队列状态可用;
offer(e, time, unit)和poll(time, unit)方法会限时阻塞调用线程,直到超时或线程被中断或队列状态可用。
public interface BlockingQueue<E> extends Queue<E> {
/**
* 插入元素e至队尾, 如果队列已满, 则阻塞调用线程直到队列有空闲空间.
*/
void put(E e) throws InterruptedException;
/**
* 插入元素e至队列, 如果队列已满, 则限时阻塞调用线程,直到队列有空闲空间或超时.
*/
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 从队首删除元素,如果队列为空, 则阻塞调用线程直到队列中有元素.
*/
E take() throws InterruptedException;
/**
* 从队首删除元素,如果队列为空, 则限时阻塞调用线程,直到队列中有元素或超时.
*/
E poll(long timeout, TimeUnit unit) throws InterruptedException;
// ...
}
除此之外,BlockingQueue还具有以下特点:
- BlockingQueue队列中不能包含null元素;
- BlockingQueue接口的实现类都必须是线程安全的,实现类一般通过“锁”保证线程安全;
- BlockingQueue 可以是限定容量的。remainingCapacity()方法用于返回剩余可用容量,对于没有容量限制的BlockingQueue实现,该方法总是返回Integer.MAX_VALUE 。