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. (20)模型层 -ORM之msql 基于双下划线的跨表查询(一对一,一对多,多对多)

    基于对象的跨表查询是子查询 基于双下划线的查询是连表查询 PS:基于双下划线的跨表查询 正向按字段,反向按表名小写 一对一 需求:查询lqz这个人的地址# 正向查询ret = models.Autho ...

  2. SQL Server 向数据库中创建表并添加数据

    创建表,展开数据库中新建的数据库,下面有一个选项-表.在该选项上右键就可以选择-新建-表. 然后出现的界面上是需要自己填写列列名.数据类型和选择是否允许空值. 其中数据类型我是参考: http://w ...

  3. 【BZOJ3144】【HNOI2013】切糕

    总算做了一道2011以后的省选题了……原题: 图片题面好评! P,Q,R≤40,0≤D≤R,给出的所有的不和谐值不超过1000. 文本样例好评! 恩这个是听妹主席讲过后会写的,首先把每个点拆成链,那么 ...

  4. Java基础七(Eclipse工具)

    今日内容介绍1.Eclipse开发工具2.超市库存管理系统 ###01Eclipse的下载安装 * A: Eclipse的下载安装  * a: 下载 * http://www.eclipse.org ...

  5. python实现单链表的翻转

    #!/usr/bin/env python #coding = utf-8 class Node:     def __init__(self,data=None,next = None):      ...

  6. Java打印九九乘法表及倒打九九乘法表

    //正打 public class Test3 { public static void main(String[] args) { for(int j=1;j<10;j++){ for(int ...

  7. Java中的继承抽象类和接口

    一.总结 1.使用extends关键字继承,eg: class Student extends Persion { ...}; 2.Java编程规范中类的首字母大写,方法的首字母小写单词首字母代谢,e ...

  8. 04基于python玩转人工智能最火框架之TensorFlow开发环境搭建

    MOOC_VM.vdl.zip 解压之后,得到一个vdl文件.打开virtual box,新建选择类型linuxubuntu 64位. 选择继续,分配2g.使用已有的虚拟硬盘文件,点击选择我们下载的文 ...

  9. lch 儿童围棋课堂 启蒙篇 (李昌镐 著)

    第1章 了解围棋 第2章 无气不活 棋子的"气"第3章 有目数才能赢空第4章 常用术语第5章 吃子第6章 死活:眼第7章 死活:典型棋形第8章 布局:术语篇 第1章 了解围棋 (已 ...

  10. C# 获取机器码

    using System.Runtime.InteropServices; using System.Management; using System; public class HardwareIn ...