Deque
是Queue
的一个子接口,是Double Ended Queue
的缩写,顾名思义Deque是一个支持双向检索
和插入
元素的双向队列
,因此Deque既支持FIFO
原则也支持LIFO
原则的数据结构,Deque接口是一种比Stack和Queue更为丰富的抽象数据形式,因为它同时实现了以上两者
主要方法
如图此接口定义时在提供了双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。因为此接口继承了队列接口Queue,所以其每种方法也存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。
FIFO行为(当队列Queue使用)
将元素添加到双端队列的末尾,从双端队列的开头移除元素。从 Queue 接口继承的方法完全等效于 Deque 方法,如下表所示:
LIFO行为(当栈Stack使用)
在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:
方法说明如下:
可以看出Deque在Queue的方法上新添了对队列头尾元素的操作,add,remove,get形式的方法会在有界队列满员和空队列时抛出异常,offer
,poll
,peek
形式的方法则会返回false
或null
.
此外方法表中需要注意push
= addFirst
,pop
= removeFirst
,只是使用了不同的方法名体现队列表示栈结构时的特点.
实现类
- LinkedList 大小可变的链表双端队列,允许元素为 null
- ArrayDeque 大下可变的数组双端队列,不允许 null
- LinkedBlockingDeque 如果队列为空时,获取操作将会阻塞,直到有元素添加
- ConcurrentLinkedDeque 非阻塞线程安全列表
工作密取
在 生产者-消费者
模式中,所有消费者都从一个工作队列中取元素,一般使用阻塞队列
实现;而在 工作密取
模式中,每个消费者有其单独的工作队列,如果它完成了自己双端队列
中的全部工作,那么它就可以从其他消费者的双端队列末尾
秘密地获取工作。
工作密取 模式 对比传统的 生产者-消费者 模式,更为灵活,因为多个线程
不会因为在同一个工作队列
中抢占内容发生竞争。在大多数时候,它们只是访问自己的双端队列
。即使需要访问另一个队列时,也是从 队列的尾部获取工作,降低了队列上的竞争程度。