Java中的DelayQueue位于java.util.concurrent包下,本质是由PriorityQueue和BlockingQueue实现的阻塞优先级队列。

放入队列的元素需要实现java.util.concurrent包的Delayed接口:

public interface Delayed extends Comparable<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);
}

通过实现这个接口,来完成对队列中元素,按照时间延迟先后排序的目的。

从队列中取元素:

看DelayedQueue的take()方法:

    /**
* Retrieves and removes the head of this queue, waiting if necessary
* until an element with an expired delay is available on this queue.
*
* @return the head of this queue
* @throws InterruptedException {@inheritDoc}
*/
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(NANOSECONDS);
if (delay <= 0)
return q.poll();
first = null; // don't retain ref while waiting
if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
available.awaitNanos(delay);
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && q.peek() != null)
available.signal();
lock.unlock();
}

可以看到,在这段代码里,在第一个元素的延迟时间还没到的情况下:

  • 如果当前没有其他线程等待,则阻塞当前线程直到延迟时间。
  • 如果有其他线程在等待,则阻塞当前线程。

向队列中放入元素:

    /**
* Inserts the specified element into this delay queue.
*
* @param e the element to add
* @return {@code true}
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
q.offer(e);
if (q.peek() == e) {
leader = null;
available.signal();
}
return true;
} finally {
lock.unlock();
}
}

在放入元素的时候,会唤醒等待中的读线程。

如果我们不考虑分布式运行和任务持久化的话,Java中的DelayQueue是一个很理想的方案,精巧好用。但是如果我们需要分布式运行和任务持久化,就需要引入一些外部组件。

延时队列:Java中的DelayQueue的更多相关文章

  1. 剑指 Offer 09. 用两个栈实现队列 +java中栈和队列的使用

    剑指 Offer 09. 用两个栈实现队列 题目链接 class CQueue { private Stack<Integer> sta1; private Stack<Intege ...

  2. java中延时队列的使用

    最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送.在翻阅java的api后,发现java中有一个延时队列可以解决这个问题 ...

  3. 阻塞队列一——java中的阻塞队列

    目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...

  4. 微服务-springboot-rabbitmq:实现延时队列

    延时队列应用于什么场景 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费.那么,为什么需要延迟消费呢?我们来看以下的场景 网上商城下订单后30分钟后没有完成支 ...

  5. Java中常用的七个阻塞队列第二篇DelayQueue源码介绍

    Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...

  6. java并发编程工具类JUC第三篇:DelayQueue延时队列

    DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的"延时时间"进行排序).另一层 ...

  7. 🏆【Java技术专区】「延时队列专题」教你如何使用【精巧好用】的DelayQueue

    延时队列前提 定时关闭空闲连接:服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. 定时清除额外缓存:缓存中的对象,超过了空闲时间,需要从缓存中移出. 实现任务超时处理:在网络协议滑动窗口请求 ...

  8. Java多线程系列- DelayQueue延时队列

    我们在开发中,有如下场景 a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之.b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出.c) 任务超时处理.在网络协议滑动窗 ...

  9. Java中的阻塞队列

    1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...

随机推荐

  1. day 020 常用模块02

    主要内容: 什么是序列化 pickle shelve json configparser(模块) 一 序列化 我们在存储数据或者网络传输数据的时候,需要对我们的对象进行处理,把对象处理成方便存储和 传 ...

  2. 内存池技术(UVa 122 Tree on the level)

    内存池技术就是创建一个内存池,内存池中保存着可以使用的内存,可以使用数组的形式实现,然后创建一个空闲列表,开始时将内存池中所有内存放入空闲列表中,表示空闲列表中所有内存都可以使用,当不需要某一内存时, ...

  3. java-类与类,类与接口,接口与接口的关系

    1.类与类: - 继承关系,只能单继承,可以多层继承. 2.类与接口: - 实现关系,可以单实现,也可以多实现. - 并且还可以在继承一个类的同时实现多个接口. - * 例:class Demo ex ...

  4. 实验吧—Web——WP之 貌似有点难

    其实这道题并不难,只要会看一点PHP语句,会用BP抓包,改包就好了 打开解题链接: 提示有:PHP代码审计,并且有一个:View the source code 的按钮 我们点击打开 打开后发现是一段 ...

  5. 实验吧—密码学——WP之 古典密码

    首先我们研究题目 1.古典密码 2.key值的固定结构 3.加密方式就在谜面里 首先看到这些数字我们就能想到ASCII,而且做题多了就能看出123是{:125是},所以得到字符串如下 OCU{CFTE ...

  6. ApplicationContext之getBean方法详解

    转自:http://www.sohu.com/a/115194552_466964 我们知道可以通过ApplicationContext的getBean方法来获取Spring容器中已初始化的bean. ...

  7. 下面有关 JAVA 异常类的描述,说法正确的有()

    都是Throwable的子类: 1.Exception(异常) :是程序本身可以处理的异常. 2.Error(错误): 是程序无法处理的错误.这些错误表示故障发生于虚拟机自身.或者发生在虚拟机试图执行 ...

  8. Easyui combobox下拉框默认选中第一项

    var val = $(#cc).combobox("getData");for (var item in val[0]) {       if (item == "gr ...

  9. LG2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

    题意 题目描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草的所有地点.对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度. 输入输出格式 ...

  10. 彻底理解一致性哈希算法(consistent hashing)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...