Queue队列,BlockingQueue阻塞队列,具有阻塞功能的队列。学习BlockingQueue主要就在于学习它的阻塞功能。
█ Queue
队列是一种先进先出(FIFO)的数据结构。Queue的单端队列,即只能从队列的一头添加元素,再从队列的这头移出元素。
实现队列的结构的有两种,顺序结构和链式结构。顺序结构的实现依赖于数组,链式结构的实现依赖于链表。
在Java中,Queue继承了Collection,因此Queue和List、Set算是兄弟姐妹。
public interface Queue<E> extends Collection<E> {
// 向队列中添加一个元素
// 如果队列已满没有足够的空间放元素了,会抛出异常
boolean add(E e);
// 向队列中添加一个元素
// 如果队列已满没有足够的空间放元素了,返回false
boolean offer(E e);
// 移出队列中队首的第一个元素,
// 如果队列为空没有元素可以移出,会抛出异常
E remove();
// 移出队列中队首的第一个元素,
// 如果队列为空没有元素可以移出,返回null
E poll();
// 返回队列中队首的第一个元素,但不移出。
// 如果队列为空没有元素可以移出,会抛出异常
E element();
// 返回队列中队首的第一个元素,但不移出。
// 如果队列为空没有元素可以移出,返回null
E peek();
}
Queue定义了上面的6个方法,用于将元素入队、出队、查看队首元素。两两一对。Queue对每个方法的行为进行约定(比如抛出异常,还是给返回值),实现类要按照约定的行为实现每个方法的行为。
入队:
add、offer提供向队列中添加元素功能。区别是当队列满了没有足够的空间存放元素时,add方法要抛出IllegalStateException异常。offer方法则要返回false表示入队失败。
出队:
remove、poll提供将队列中元素移出队列的功能。区别是当队列为空没有元素可以移除时,remove方法要抛出NoSuchElementException。poll方法则要返回null表示没有元素。
查看队首元素:
element、peek提供查看队首元素功能,两者都只是查看,但不会移除队首元素。区别是当队列为空没有元素时,element方法要抛出NoSuchElementException异常,peek方法则返回null表示没有元素。
█ BlockingQueue
BlockingQueue继承Queue,在具有Queue提供的方法之外,BlockingQueue还提供了下面几个方法用于实现其BlockingQueue功能。
/ 往队列中添加元素,
// 如果队列已满没有足够的空间存在,则会一直等待,等待队列有额外的空间来存放此元素
void put(E e) throws InterruptedException;
// 带有等待超时时间限制的添加元素,
// 当队列已满,等待设置的时间长度,在等待时间内添加成功则返回true,失败则返回false
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
// 从队列中移出元素
// 如果队列为空没有元素可以移出,其会一直阻塞等待,直到队列中有元素。
E take() throws InterruptedException;
// 带有等待超时时间限制的移出元素。
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
BlockingQueue在Queue提供的方法基础上,扩展了上面的几个方法来提供阻塞的特点。BlockingQueue约定这几个方法的阻塞等待行为,实现类要按照约定来实现具体的逻辑。
入队:
put、offer提供向队列中添加元素的操作。区分是当队列满了没有足够的空间可以添加元素时,put方法会一直阻塞等待,直到队列有了额外的空间。如果队列始终保持满的状态,则put方法会一直阻塞等待下去。offer方法在队列满时,也会等待,但它不会一直等待下去,可以设置其最多等待的时长,如果等待的时长达到了设置的时间,入队成功返回true,入队失败返回false。
出队:
take、poll提供将队列中的队首元素移出的功能。区别是当队列为空,没有元素可以移出的时候,take方法会一直阻塞等待,直到队列中有元素可以移出了。poll方法则提供了超时等待的功能,在设置的等待时长内,没有有元素可以移出则返回该元素,如果队列还为空没有元素可以移出,则直接返回null。
实现类:
从上图可以看见,BlockingQueue有很多实现类,BlockingQueue也是一个大家庭。
BlockingQueue的实现类很多,主要介绍ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、BlockingDeque(双端队列,从队列的两端都能添加和移出元素)。