DelayQueue简单介绍

DelayQueue:一个使用优先级队列实现的无界阻塞队列。

支持延时获取的元素的阻塞队列,元素必须要实现Delayed接口。

适用场景:实现自己的缓存系统,订单到期,限时支付等等。

具体代码会有注释,很好理解!

这里我们模拟一个订单延时处理的demo

首先我们定义一个订单实体类

/*** 订单实体类* @author James Lee**/
public class Order {// 订单编号private String orderId;// 订单金额private Double orderMoney;// 省略get、set等方法}

创建存到队列里的元素

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/*** 存到队列里的元素* 支持延时获取的元素的阻塞队列,元素必须要实现Delayed接口。* 根据订单有效时间作为队列的优先级* @param <T>*/
public class ItemVo<T> implements Delayed{// 到期时间 单位:msprivate long activeTime;// 订单实体(使用泛型是因为后续扩展其他业务共用此业务类)private T data;public ItemVo(long activeTime, T data) {super();// 将传入的时间转换为超时的时刻this.activeTime = TimeUnit.NANOSECONDS.convert(activeTime, TimeUnit.MILLISECONDS) + System.nanoTime();this.data = data;}public long getActiveTime() {return activeTime;}public T getData() {return data;}// 按照剩余时间进行排序@Overridepublic int compareTo(Delayed o) {// 订单剩余时间-当前传入的时间= 实际剩余时间(单位纳秒)long d = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);// 根据剩余时间判断等于0 返回1 不等于0 // 有可能大于0 有可能小于0  大于0返回1  小于返回-1return (d == 0) ? 0 : ((d > 0) ? 1 : -1);}// 获取剩余时间@Overridepublic long getDelay(TimeUnit unit) {// 剩余时间= 到期时间-当前系统时间,系统一般是纳秒级的,所以这里做一次转换long d = unit.convert(activeTime-System.nanoTime(), TimeUnit.NANOSECONDS);return d;}}

创建订单生成类

import java.util.concurrent.DelayQueue;/*** 模拟订单插入的功能*/
public class PutOrder implements Runnable {// 使用DelayQueue:一个使用优先级队列实现的无界阻塞队列。private DelayQueue<ItemVo<Order>> queue;public PutOrder(DelayQueue<ItemVo<Order>> queue) {super();this.queue = queue;}@Overridepublic void run() {/*** 这里模拟淘宝、京东、苏宁的订单,淘宝是5秒到期,京东是10秒到期,苏宁是15秒到期*/// 淘宝订单插入Order tbOrder = new Order("tb001", 9.9);ItemVo<Order> itemVoTb = new ItemVo<Order>(5000, tbOrder);queue.offer(itemVoTb);System.out.println("淘宝订单5秒后过期:" + tbOrder.getOrderId());// 京东订单插入Order jdOrder = new Order("jd002", 19.9);ItemVo<Order> itemVoJd = new ItemVo<Order>(10000, jdOrder);queue.offer(itemVoJd);System.out.println("京东订单10秒后过期:" + jdOrder.getOrderId());// 苏宁订单插入Order snOrder = new Order("sn003", 29.9);ItemVo<Order> itemVoSn = new ItemVo<Order>(15000, snOrder);queue.offer(itemVoSn);System.out.println("苏宁订单15秒后过期:" + tbOrder.getOrderId());}
}

创建订单过期取出类

import java.util.concurrent.DelayQueue;
/*** 取出到期的订单的功能*/
public class FetchOrder implements Runnable{// 使用DelayQueue:一个使用优先级队列实现的无界阻塞队列。private DelayQueue<ItemVo<Order>> queue;public FetchOrder(DelayQueue<ItemVo<Order>> queue) {super();this.queue = queue;}@Overridepublic void run() {while(true) {try {// 使用DelayQueue的take方法获取当前队列里的元素(take方法是阻塞方法,如果队列里有值则取出,否则一直阻塞)ItemVo<Order> itemVo = queue.take();// 获取元素的实体对象,保险起见做一次强制转型Order order = (Order)itemVo.getData();System.out.println("订单:" + order.getOrderId()+ " 已过期!已从订单队列里剔除!");} catch (InterruptedException e) {e.printStackTrace();}}}}

测试代码

import java.util.concurrent.DelayQueue;/*** 测试*/
public class Test {public static void main(String[] args) throws InterruptedException {DelayQueue<ItemVo<Order>> queue = new DelayQueue<ItemVo<Order>>();// 插入订单new Thread(new PutOrder(queue)).start();// 取出过期订单的线程new Thread(new FetchOrder(queue)).start();// 为了看到效果,这里没个一秒打印一次时间,一共15秒,打印15次。for (int i = 1; i <= 15; i++) {Thread.sleep(1000);System.out.println("========================="+ i);}}
}

测试结果

淘宝订单5秒后过期:tb001
京东订单10秒后过期:jd002
苏宁订单15秒后过期:tb001
=========================1
=========================2
=========================3
=========================4
订单:tb001 已过期!已从订单队列里剔除!
=========================5
=========================6
=========================7
=========================8
=========================9
订单:jd002 已过期!已从订单队列里剔除!
=========================10
=========================11
=========================12
=========================13
=========================14
订单:sn003 已过期!已从订单队列里剔除!
=========================15

结果分析

使用Java延时队列DelayQueue实现订单延时处理相关推荐

  1. JAVA中的延时队列DelayQueue

    Java中的延时队列DelayQueue是基于优先队列PriorityQueue实现的. 注:PriorityQueue是基于堆(Heap)实现的.堆(Heap)在本质上是一个数组. Priority ...

  2. 【java】6个延时队列的实现方案

    1.概述 转载:6个延时队列的实现方案 [编者的话]个人比较喜欢一些实践类的东西,既学习到知识又能让技术落地,能搞出个demo最好,本来不知道该分享什么主题,好在最近项目紧急招人中,而我有幸做了回面试 ...

  3. java延时_Java实现延时任务——DelayQueue

    应用开发过程中,我们常常需要用到延时任务的地方, 举个栗子: 在我们提交订单之后,15分钟内未支付则需要自动取消订单,当然,实现的方式有很多种,我们尝试用延时任务方式进行. java里自带的延时队列- ...

  4. java实现延时队列

    延时队列主要应用场景是用户登录后延时推送消息,通知等,一般用mq中间件来弄,下面我来用java实现一.消息实体类实现Delayed接口 import lombok.Data;import java.u ...

  5. Delayed延时队列 来实现关闭已超时的任务或订单

    目录 1.定义延时订单类 2.处理超时订单实现类 3.在创建订单或任务的方法中加入延时队列 1.定义延时订单类 定义唯一的订单编号.活动ID.超时时间.类型等你业务可能需要用到的字段 类需要实现Del ...

  6. 一口气说出 6种 延时队列的实现方案,大厂offer稳稳的

    下边会介绍多种实现延时队列的思路,文末提供有几种实现方式的 github地址.其实哪种方式都没有绝对的好与坏,只是看把它用在什么业务场景中,技术这东西没有最好的只有最合适的. 一.延时队列的应用 什么 ...

  7. 一口气说出 6 种延时队列的实现方法,面试官满意的笑了

    这是我的第 193 期分享 作者 | 程序员内点事 来源 | 程序员内点事(ID:chegnxy-nds) 分享 | Java中文社群(ID:javacn666) 五一期间原计划是写两篇文章,看一本技 ...

  8. 一口气说出 6种 延时队列的实现方法,面试官也得服

    一.延时队列的应用 什么是延时队列?顾名思义:首先它要具有队列的特性,再给它附加一个延迟消费队列消息的功能,也就是说可以指定队列中的消息在哪个时间点被消费. 延时队列在项目中的应用还是比较多的,尤其像 ...

  9. 延时队列的几种实现方式

    延时队列的几种实现方式 何为延迟队列? 顾名思义,首先它要具有队列的特性,再给它附加一个延迟消费队列消息的功能,也就是说可以指定队列中的消息在哪个时间点被消费. 延时队列能做什么? 延时队列多用于需要 ...

最新文章

  1. 手机画面尺寸多少满屏_手机屏幕科普
  2. 简单实现Dedecms RSS全站输出
  3. 【Boost】boost库中thread多线程详解13——线程标识符
  4. md文件生成Java代码_Beetlsql自定义生成entity,mapper,md代码
  5. Android找工作系列之自定义View
  6. org.attoparser.ParseException: Could not parse as expression: “
  7. 12306能删候补订单记录_2019最新火车候补购票十大问题
  8. 阿里第九版Java系统架构师+应用架构师面试突击宝典
  9. 这是我经历过最惨的转正答辩了
  10. LeetCode 到最近的人的最大距离
  11. PLC MODBUS RTU读写IC卡操作
  12. 携程去哪儿合并可行性研究报告
  13. 微信公众号开发 (1) 微信接入认证成为开发者
  14. Android天气预报项目
  15. 一周新论文 | 2020年第13周 | 自然语言处理相关
  16. 定位职业赛道-抽象职业能力-修炼核心能力,打造核心竞争力,不单纯被岗位、公司、行业的选择局限
  17. The Leaky Integrate-and-Fire (LIF) Neuron Mode-LIF神经元模型
  18. R语言绘制SCI论文中常见的箱线散点图,并自动进行方差分析计算显著性水平
  19. 2022-2028年中国水声通信行业市场发展潜力及投资前景分析报告
  20. 超详细教你Dreamweaver如何绑定GitHub仓库

热门文章

  1. java 两个经纬度 距离_Java 根据两个经纬度,得到两点距离
  2. 如何在数据库中存储大的数据文件
  3. VS中MessageBox与AfxMessageBox用法与区别
  4. 微信小程序--手机号解密!必成功!!!
  5. 嵌入式知识-ARM裸机-学习笔记(12):ADC模数转换器
  6. 阅读极度舒适,Python 美化你的 Excel 表格!
  7. 华为云FusionInsight MRS HDFS组件数据存储策略配置指导
  8. 解决:表单选择框等数据选择了不显示但是查看数据确实是选择成功了的
  9. SQLMap使用攻略
  10. python向windows服务器上传文件(夹)