Deque与LinkedBlockingDeque深入分析

Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque。这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂。下图描述的是Deque的完整体系图。需要说明的是LinkedList也已经加入了Deque的一部分(LinkedList是从jdk1.2 开始就存在数据结构)。

 


Deque在Queue的基础上增加了更多的操作方法。


从上图可以看到,Deque不仅具有FIFO的Queue实现,也有FILO的实现,也就是不仅可以实现队列,也可以实现一个堆栈。

同时在Deque的体系结构图中可以看到,实现一个Deque可以使用数组(ArrayDeque),同时也可以使用链表(LinkedList),还可以同实现一个支持阻塞的线程安全版本队列LinkedBlockingDeque。


1、ArrayDeque实现Deque

 


对于数组实现的Deque来说,数据结构上比较简单,只需要一个存储数据的数组以及头尾两个索引即可。由于数组是固定长度的,所以很容易就得到数组的头和尾,那么对于数组的操作只需要移动头和尾的索引即可。

特别说明的是ArrayDeque并不是一个固定大小的队列,每次队列满了以后就将队列容量扩大一倍(doubleCapacity()),因此加入一个元素总是能成功,而且也不会抛出一个异常。也就是说ArrayDeque是一个没有容量限制的队列。

同样继续性能的考虑,使用System.arraycopy复制一个数组比循环设置要高效得多。


1.1、ArrayDeque的源码解析


 

[java]  view plain copy
  1. //数组双端队列ArrayDeque的源码解析  
  2. public class ArrayDeque extends AbstractCollection implements Deque, Cloneable, Serializable{  
  3.       
  4.     private transient E[] elements;  
  5.       
  6.     private transient int head;  
  7.       
  8.     private transient int tail;  
  9.       
  10.     private static final int MIN_INITIAL_CAPACITY 8 
  11.     // ******  Array allocation and resizing utilities ******  
  12.       
  13.     private void allocateElements(int numElements)  
  14.         int initialCapacity MIN_INITIAL_CAPACITY;  
  15.         if (numElements >= initialCapacity)  
  16.             initialCapacity numElements;  
  17.             initialCapacity |= (initialCapacity >>>  1);  
  18.             initialCapacity |= (initialCapacity >>>  2);  
  19.             initialCapacity |= (initialCapacity >>>  4);  
  20.             initialCapacity |= (initialCapacity >>>  8);  
  21.             initialCapacity |= (initialCapacity >>> 16);  
  22.             initialCapacity++;  
  23.             if (initialCapacity 0  // Too many elements, must back off  
  24.                 initialCapacity >>>= 1;// Good luck allocating 30 elements  
  25.          
  26.         elements (E[]) new Object[initialCapacity];  
  27.      
  28.       
  29.     private void doubleCapacity()  
  30.         assert head == tail;  
  31.         int head;  
  32.         int elements.length;  
  33.         int p; // number of elements to the right of p  
  34.         int newCapacity << 1 
  35.         if (newCapacity 0 
  36.             throw new IllegalStateException("Sorry, deque too big");  
  37.         Object[] new Object[newCapacity];  
  38.         System.arraycopy(elements, p, a, 0r);  
  39.         System.arraycopy(elements, 0a, r, p);  
  40.         elements (E[])a;  
  41.         head 0 
  42.         tail n;  
  43.      
  44.       
  45.     private  T[] copyElements(T[] a)  
  46.         if (head tail)  
  47.             System.arraycopy(elements, head, a, 0size());  
  48.         else if (head tail)  
  49.             int headPortionLen elements.length head;  
  50.             System.arraycopy(elements, head, a, 0headPortionLen);  
  51.             System.arraycopy(elements, 0a, headPortionLen, tail);  
  52.          
  53.         return a;  
  54.      
  55.       
  56.     public ArrayDeque()  
  57.         elements (E[]) new Object[16];  
  58.      
  59.       
  60.     public ArrayDeque(int numElements)  
  61.         allocateElements(numElements);  
  62.      
  63.       
  64.     public ArrayDeque(Collection
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值