//一个基于二叉堆优先级的延迟取出队列。
//先看构造函数。
public DelayQueue() {}
public DelayQueue(Collection<? extends E> c) {
this.addAll(c);
}
//将collection插入到内部的PriorityQueue中。
public boolean addAll(Collection<? extends E> c) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
//插入元素是插入到内部的PriorityQueue中。
public boolean offer(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
q.offer(e);
//如果插入的是头元素(即当前头元素变了)
if (q.peek() == e) {
//将leader线程置为null
leader = null;
//唤醒等待的线程
available.signal();
}
return true;
} finally {
lock.unlock();
}
}
public boolean offer(E e, long timeout, TimeUnit unit) {
return offer(e);
}
public void put(E e) {
offer(e);
}
//获取元素但是并不移出
public E peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
//用底层的priorityQueue实现。
return q.peek();
} finally {
lock.unlock();
}
}
//获取头元素如果头元素为空或者还没有到出列时间返回null。
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取头元素
E first = q.peek();
//如果头元素是空或者获取到的头元素还没有到出列时间返回null
if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
return null;
else
return q.poll();
} finally {
lock.unlock();
}
}
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
E first = q.peek();
//如果没空
if (first == null) {
//超时了返回null
if (nanos <= 0)
return null;
else
//挂起当前线程nanos时间
nanos = available.awaitNanos(nanos);
} else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
//到时间了可以取出
if (delay <= 0)
return q.poll();
//超时了返回null
if (nanos <= 0)
return null;
//如果等待时间小于出列时间或者leader线程!=null则挂起当前线程
if (nanos < delay || leader != null)
nanos = available.awaitNanos(nanos);
else {
//没有其他leader线程则将自己置为leader线程
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
long timeLeft = available.awaitNanos(delay);
nanos -= delay - timeLeft;
} finally {
//如果leader是自己
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
//释放锁
if (leader == null && q.peek() != null)
available.signal();
lock.unlock();
}
}
//可阻塞的获取队列头结点
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
E first = q.peek();
//没有获取到则等待
if (first == null)
available.await();
else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
//到达队列出列时间返回
if (delay <= 0)
return q.poll();
//如果leader不等于null阻塞当前线程让leader线程取走当前元素
else if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
//当前线程设置为leader
leader = thisThread;
try {
//等待delay时间被唤醒
available.awaitNanos(delay);
} finally {
//醒来之后如果我是leader让其他线程变为leader。
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
//如果leader为空并且有头唤醒其他线程。
if (leader == null && q.peek() != null)
available.signal();
lock.unlock();
}
}
/**leader线程是当前正在获取头节点的线程。在offer的时候如果插入的元素变为了头结点,
此时将leader置为null,重新竞争leader。
DelayQueen内部使用的是一个PriorityQueen类实现,所以可以保证插入顺序的优先级。
然后根据实现Delayed接口的getDelay方法来获取元素是否已经到出列时间。
*/
//获取队列长度
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return q.size();
} finally {
lock.unlock();
}
}
//获取容量(没有容量限制所以返回integer最大值)
public int remainingCapacity() {
return Integer.MAX_VALUE;
}
//移除元素
public boolean remove(Object o) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return q.remove(o);
} finally {
lock.unlock();
}
}
public Object[] toArray() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return q.toArray();
} finally {
lock.unlock();
}
}
public <T> T[] toArray(T[] a) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return q.toArray(a);
} finally {
lock.unlock();
}
}
//移出队列中的可用元素并将他们封装到collection中
public int drainTo(Collection<? super E> c) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
int n = 0;
for (;;) {
E first = q.peek();
if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
break;
c.add(q.poll());
++n;
}
return n;
} finally {
lock.unlock();
}
}
//最多移除maxElements个可用元素到collection中。
public int drainTo(Collection<? super E> c, int maxElements) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int n = 0;
while (n < maxElements) {
E first = q.peek();
if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
break;
c.add(q.poll());
++n;
}
return n;
} finally {
lock.unlock();
}
}
分享到:
相关推荐
微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码...
易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar
小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 ...
在这个“微信小程序开发-绘本跟读案例源码.zip”压缩包中,包含了用于创建一个绘本跟读功能的小程序的全部源代码,非常适合开发者学习和参考。 首先,我们要理解绘本跟读的功能。绘本跟读是教育类应用中常见的一种...
【标题】"英语绘本听跟读小程序源码"所涉及的知识点主要集中在移动应用开发、语音识别技术以及教育软件设计上。这个项目是一款专为英语学习者设计的小程序,其核心功能是听读英语绘本,并且能与智能评分系统对接,...
在这个"悦读-uniApp源码.zip"压缩包中,我们可以推测它包含了一个名为"悦读"的阅读应用的前端源代码。uniApp的项目结构通常包括以下几个主要部分: 1. **main.js**:这是uniApp项目的入口文件,定义了全局配置,如...
基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)...
易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象...
易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar ...
C#winform读xml源码(适合新手)http://www.cnblogs.com/a1656344531/archive/2012/11/28/2792863.html跟着这个教程做的,网址中有不少小错误会让新手比较抓狂,所以附上源码给各位新手,希望你能帮到大家。
经过一段时间的Android编程学习后,写了这个比较综合的android阅读类的APP应用,附上了完整的源代码,源代码部分包括了阅读应用APP的源码,以及服务器程序,我给这个阅读小程序起名字叫做“指读”。这里的服务端数据...
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...
微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip ...
基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表...
易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件...
易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读...
【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大...
Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码...
(微信小程序毕业设计)悦读神器(附源码+截图).zip(微信小程序毕业设计)悦读神器(附源码+截图).zip(微信小程序毕业设计)悦读神器(附源码+截图).zip(微信小程序毕业设计)悦读神器(附源码+截图).zip(微信小程序毕业设计)...