Queue & BlockingQueue

Queue(队列)

java.util.Queue
Queue 提供了入队、出队、获取队列头的方法。

这些方法分两类:
一类是在操作失败时抛出异常;
另一类是在操作失败时返回一个特殊的值(null或false)。
操作失败的情况都与队列的临界条件有关:队列满或者队列空。队列满的时候入队会失败,队列空的时候出队会失败。

队列通常以FIFO(先进先出)的方式对元素排序。
(但不一定都是FIFO,比如:PriorityQueue)

队列实现通常不允许插入null元素,因为poll方法将null用作特殊的返回值,以指示队列不包含任何元素。

Queue 接口没有定义那些在并发编程中很常见的阻塞队列方法(比如:等待队列非空或者等待队列空间可用)。这些方法是在 java.util.concurrent.BlockingQueue 接口中定义的,它扩展了 Queue 接口。

java.util.Queue#add(E e)
增加一个元素。如果队列已满,则抛出 IllegalStateException

java.util.Queue#offer(E e)
添加一个元素并返回 true。如果队列已满,则返回false

java.util.Queue#remove()
移除并返回队列头部的元素。如果队列为空,则抛出 NoSuchElementException

java.util.Queue#poll()
移除并返问队列头部的元素。如果队列为空,则返回 null

java.util.Queue#element()
返回队列头部的元素。如果队列为空,则抛出 NoSuchElementException

java.util.Queue#peek()
返回队列头部的元素。如果队列为空,则返回 null。(peek 是窥视、偷看的意思)

 BlockingQueue(阻塞队列)

java.util.concurrent.BlockingQueue
BlockingQueue 继承了 Queue 接口,它在 Queue 的基础上,额外支持了操作失败(当队列为空或者队列空间满了)时的阻塞操作
也就是说,当列表为空时,BlockingQueue 支持阻塞获取队列头部元素,直到队列变为非空;
当列表空间满了时候,BlockingQueue 支持阻塞添加元素,直到队列空间变为可用。

BlockingQueue 支持的阻塞操作分了两类:一种是无限期的阻塞;另一种是给定时间的阻塞。

java.util.concurrent.BlockingQueue#put(E e)
添加一个元素。如果队列满,则阻塞

java.util.concurrent.BlockingQueue#offer(E e, long timeout, TimeUnit unit)
添加一个元素。如果队列满,则阻塞指定的时间

java.util.concurrent.BlockingQueue#take()
移除并返回队列头部的元素。如果队列为空,则阻塞

java.util.concurrent.BlockingQueue#poll(long timeout, TimeUnit unit)
移除并返回队列头部的元素。如果队列为空,则阻塞指定的时间

 

在并发队列上,JDK 提供了2套实现:
一个是以 ConcurrentLinkedQueue 为代表的高性能非阻塞队列
另一个是以 BlockingQueue 接口为代表的阻塞队列,无论哪种都继承自Queue。
使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环CAS的方式来实现

参考:
https://www.cnblogs.com/lemon-flm/p/7877898.html
https://blog.51cto.com/zhangfengzhe/1878323

原文地址:https://www.cnblogs.com/kevin-yuan/p/13549948.html