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. (18)jq事件操作

    jq的私人网站:http://jquery.cuishifeng.cn/ 具体的查看上面的网站 <!DOCTYPE html><html><head> <me ...

  2. [codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]

    http://codeforces.com/contest/1054/problem/D 题目大意:一个序列a1 a2...an,可以对若干个元素进行取反,使所得的新序列异或和为0的区间个数最多. 题 ...

  3. 命令提示符操作及Java的特点

    day1_3 命令提示符的操作 GUI 图形化方式(可视化) CLI 命令行方式 (编程方式) dir 列出当前目录下文件及文件夹 md 创建文件夹 rd 删除文件夹(只能删除空文件夹) cd 进入指 ...

  4. LG3187 [HNOI2007]最小矩形覆盖

    题意 题目描述 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点坐标 输入输出格式 输入格式: 第一行为一个整数n(3<=n<=50000),从第2至第 ...

  5. jsp页面继承

    功能类似 django template 中的  extends 功能 使用 1.需要下载rapid-core-4.0.jar    导入到web-inf下lib中   下载地址   http://w ...

  6. SQLite数据库下载

    一:SQLite简介 SQLite是一种嵌入式数据库,它的数据库就是一个文件.体积很小,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成. 要操作关系数据库,首先需要连接到 ...

  7. Java-简单的计算器(只能进行加法运算)

    有两个关键的地方: 其一: JTextField field=new JTextField(10); 这是一个文本输入框,里面的参数10的意思是,这个输入框的长度为10列 其二:点击求和按钮,出结果 ...

  8. MySQL Disk--SSD和HDD的性能

    ========================================================= 机械硬盘的性能 7200转/分的STAT硬盘平均物理寻道时间是9ms 10000转/ ...

  9. ncm 让跨项目配置一致性简单的工具

    多团队写作,确保node 项目依赖以及配置一致性是比较难搞的,所以一些大型的团队 以及框架都是使用单体仓库的模式,比如lerna 等工具. ncm 借鉴了helm .mrm.kyt.yarn 等开发工 ...

  10. MATLAB中多个一维数组的合并

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013538664/article/details/37673711 1.一维数组直接合并      ...