专做网页的网站,为你做的网站,什么网站专做二手名表,的wordpress主题一#xff0c;延迟任务应用场景#xff1f; 一般用于处理订单#xff0c;将redis中的数据延迟存入数据库#xff0c;实现异步存储减少DB的压力 二#xff0c; 延迟任务的实现方案有很多 DelayQueue Redisson MQ 时间轮 原理 JDK自带延迟队列#xff0c;基于阻塞队列…一延迟任务应用场景 一般用于处理订单将redis中的数据延迟存入数据库实现异步存储减少DB的压力 二 延迟任务的实现方案有很多 DelayQueue Redisson MQ 时间轮 原理 JDK自带延迟队列基于阻塞队列实现。 基于Redis数据结构模拟JDK的DelayQueue实现 利用MQ的特性。例如RabbitMQ的死信队列 时间轮算法 优点 不依赖第三方服务 分布式系统下可用 不占用JVM内存 分布式系统下可以 不占用JVM内存 不依赖第三方服务 性能优异 缺点 占用JVM内存 只能单机使用 依赖第三方服务 依赖第三方服务 只能单机使用 三延迟任务的原理 1DelayQueue的源码
public class DelayQueueE extends Delayed extends AbstractQueueEimplements BlockingQueueE {private final transient ReentrantLock lock new ReentrantLock();private final PriorityQueueE q new PriorityQueueE();// ... 略
} DelayQueue实现了BlockingQueue接口是一个阻塞队列。队列就是容器用来存储东西的. DelayQueue的泛型定义 E extends Delayed 这说明存入DelayQueue内部的元素必须是Delayed类型 进一步查看Delay接口
public interface Delayed extends ComparableDelayed {/*** 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);
}
看完之后我们先不管 继续看他的父类ComparableDelayed
里面有一个方法用于比较大小 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 DelayTaskD 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.初始化延迟队列
DelayQueueDelayTaskString queue new DelayQueue();
// 2.向队列中添加延迟执行的任务 //当前延迟时间是Second
queue.add(new DelayTask(延迟任务数据可以是方法, Duration.ofSeconds(延迟时间)));
// 3.尝试执行任务
DelayTaskString task queue.take();
//执行延迟队列中的任务
task.getData()