Java DelayQueue 延时队列
优先队列 PriorityQueue
DelayQueue使用PriorityQueue实现。
优先队列:PriorityQueue
底层数据结构:数组
默认初始长度: 11
扩容策略:Double size if small; else grow by 50% 当前长度小于64时double,否则长度增加50%。
原理:
实质是一个堆,堆分为大根堆和小根堆,优先队列默认是一个小根堆。堆是一种特殊的二叉树,如果是小根堆,树上每个节点的值都小于其左右子节点。这样堆顶元素就是所有节点中最小的一个节点。将堆顶节点移出后,将最后一个节点放到堆顶,然后从堆顶向下调整,经过logn次操作即可保证堆的性质。如果要添加新元素,将新元素添加到最后,然后从堆底向上调整,同样经过logn次操作即可保证堆的性质。
优先队列的底层数据结构是一个数组,因为堆是一个完全二叉树,所以可以用数组来模拟。例如同一个节点的下标为x。该节点的父节点的下标为(x-1)/2,该节点的左右子节点的下标为:2x+1、2x+2。
DelayQueue
DelayQueue提供了在指定时间获取队列元素的功能。offer、add等方法向队列中添加一个元素。take、poll等方法获取元素,但只有当该元素到期才能获得元素。
DelayQueue中的元素必须实现Delayed
接口,该接口提供了一个方法:
/**
* Returns the remaining delay associated with this object, in the
* given time unit.
*
* @param unit the time unit
* @return the remaining delay; zero or negative values indicate
* that the delay has already elapsed
*/
long getDelay(TimeUnit unit);
要求以给定的时间单位返回当前元素还有多久到期。
在DelayQueue中会调用元素的该方法来判断元素是否到期。
dq(DelayQueue)中主要的成员变量如下:
private final transient ReentrantLock lock = new ReentrantLock();
private final PriorityQueue<E> q = new PriorityQueue<E>();
private Thread leader = null;
private final Condition available = lock.newCondition();
底层数据结构:PriorityQueue
因为PriorityQueue不是线程安全的,所以需要使用ReentrantLock同步。
当添加一个元素时,直接向PriorityQueue中添加一个元素。PriorityQueue会调用元素的compareTo方法(自己实现)进行调整。在堆顶的元素就是最快到期的元素。
核心方法:take和offer
public boolean