当前位置: 首页 > news >正文

延迟任务基于DeyalQueue

一,延迟任务应用场景?


一般用于处理订单,将redis中的数据延迟存入数据库,实现异步存储减少DB的压力

二, 延迟任务的实现方案有很多


DelayQueue

Redisson

MQ

时间轮

原理

JDK自带延迟队列,基于阻塞队列实现。

基于Redis数据结构模拟JDK的DelayQueue实现

利用MQ的特性。例如RabbitMQ的死信队列

时间轮算法

优点

  • 不依赖第三方服务

  • 分布式系统下可用

  • 不占用JVM内存

  • 分布式系统下可以

  • 不占用JVM内存

  • 不依赖第三方服务

  • 性能优异

缺点

  • 占用JVM内存

  • 只能单机使用

  • 依赖第三方服务

  • 依赖第三方服务

  • 只能单机使用

三,延迟任务的原理


 1,DelayQueue的源码

public class DelayQueue<E extends Delayed> extends AbstractQueue<E>implements BlockingQueue<E> {private final transient ReentrantLock lock = new ReentrantLock();private final PriorityQueue<E> q = new PriorityQueue<E>();// ... 略
}
  •  DelayQueue实现了BlockingQueue接口,是一个阻塞队列。队列就是容器,用来存储东西的.
  • DelayQueue的泛型定义

    • <E extends Delayed> 

  • 这说明存入DelayQueue内部的元素必须是Delayed类型

 进一步查看Delay接口

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);
}

看完之后我们先不管 ,继续看他的父类Comparable<Delayed>

里面有一个方法,用于比较大小

2,从源码中可以看出,Delayed类型必须具备两个方法:

  • getDelay():获取延迟任务的剩余延迟时间

  • compareTo(T t):比较两个延迟任务的延迟时间,判断执行顺序

    • 根据源码中的注解可以看出

      • zero or negative values indicate * that the delay has already elapsed

      • 零或者负值表示延迟已经过去

四,DelayQueue的用法


1,定义一个延迟任务的工具类

package com.tianji.learning.utils;import lombok.Data;import java.time.Duration;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;@Data
public class DelayTask<D> implements Delayed {private D data;    //用于存放延迟任务的数据private long deadlineNanos;    //延迟任务延迟到什么时候/***    delayTime    延迟多长时间*/public DelayTask(D data, Duration delayTime) {this.data = data;//用当前时间和需要延迟的时间相加得到的结果就是延迟任务延迟结束的时间this.deadlineNanos = System.nanoTime() + delayTime.toNanos();}/***    这个方法是用于获取延迟任务的剩余时间*/@Overridepublic long getDelay(TimeUnit unit) {return unit.convert(Math.max(0, deadlineNanos - System.nanoTime()), TimeUnit.NANOSECONDS);}//将队列中的延迟任务的剩余时间进行比较,然后进行排队@Overridepublic int compareTo(Delayed o) {long l = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);if(l > 0){return 1;}else if(l < 0){return -1;}else {return 0;}}
}

2,使用延迟队列

// 1.初始化延迟队列
DelayQueue<DelayTask<String>> queue = new DelayQueue<>();
// 2.向队列中添加延迟执行的任务                        //当前延迟时间是Second
queue.add(new DelayTask<>("延迟任务数据,可以是方法", Duration.ofSeconds(延迟时间)));
// 3.尝试执行任务
DelayTask<String> task = queue.take();
//执行延迟队列中的任务
task.getData()

http://www.lryc.cn/news/310338.html

相关文章:

  • Linux 查询端口被占用命令
  • 【c++】string类---标准库中的string类
  • GO语言学习笔记(与Java的比较学习)(五)
  • Sora:探索大型视觉模型的前世今生、技术内核及未来趋势
  • 基于springboot实现图书馆管理系统项目【项目源码+论文说明】计算机毕业设计
  • MATLAB环境下基于高斯滤波器-广义拉普拉斯算子的细胞核自动检测
  • 【探索AI】十一 深度学习之第1周:深度学习概述与基础
  • 【简说八股】Spring事务失效可能是哪些原因?
  • 【语音识别】- CTC损失计算的原理
  • MySQL字符集和比较规则
  • 备忘录模式(Memento Pattern)
  • LeetCode 刷题 [C++] 第121题.买卖股票的最佳时机
  • ORACLE 基础
  • Adobe illustrator CEP插件调试
  • 学会玩游戏,智能究竟从何而来?
  • Unity 常用操作
  • 【计算机网络_应用层】协议定制序列化反序列化
  • Doris实战——银联商务实时数仓构建
  • 代码随想录算法训练营第七天
  • 文件操作和IO(2):Java中操作文件
  • 人工智能-零基础
  • 网络爬虫部分应掌握的重要知识点
  • git命令笔记
  • 微服务day03-Nacos配置管理与Nacos集群搭建
  • DFS剪枝
  • 基于SpringBoot多模块项目引入其他模块时@Autowired无法注入
  • 每日一题——LeetCode1566.重复至少K次且长度为M的模式
  • 代码随想录刷题笔记-Day27
  • 【小沐学GIS】QGIS安装和入门使用
  • 黑马程序员——接口测试——day03——Postman断言、关联、参数化