利用java写的java.util.concurrent.Delayed 类 配合线程实现延迟队列处理方案

直接分享代码

package com.xxx.init.delayJob;import lombok.Data;import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;/*** User:Json* Date: 2024/5/15* java 内置的延迟队列* 服务器重启后,数据全部消失,怕宕机* 他是无界队列 可以一直放 有可能导致内存满的问题* 所以不宜处理 任务比较多的业务* 用来处理 任务少并不是很重要的数据* 如果数据放的太快 有可能 顺序也会错 **/
@Data
public class DelayTask<T>  implements Delayed {final private T data;final private long expire;/*** 构造延时任务* @param data      业务数据* @param expire    任务延时时间(ms) 分钟*/public DelayTask(T data, long expire) {super();this.data = data;this.expire =  expire * 60 * 1000 + System.currentTimeMillis();}//返回任务的剩余延迟时间,用于决定任务何时可以从队列中取出@Overridepublic long getDelay(TimeUnit unit) {return unit.convert(this.expire - System.currentTimeMillis(), unit);}// 比较两个延迟任务的优先级,决定它们在队列中的顺序//如果delta等于0,说明两个任务的延迟时间相同,返回0。//如果delta小于0,说明当前任务的延迟时间小于另一个任务,返回-1,表示当前任务优先级更高。//如果delta大于0,说明当前任务的延迟时间大于另一个任务,返回1,表示当前任务优先级更低。@Overridepublic int compareTo(Delayed o) {long delay1 = getDelay(TimeUnit.NANOSECONDS);long delay2 = o.getDelay(TimeUnit.NANOSECONDS);return Long.compare(delay1, delay2);}
}
package com.xxx.iotjava.utils;import com.xxx.init.delayJob.DelayTask;
import com.xxx.iotjava.entities.SkeAirCdRealtimeData;
import com.xxx.iotjava.job.AicCdJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;import javax.annotation.PreDestroy;
import java.time.LocalDateTime;
import java.util.concurrent.DelayQueue;/*** User:Json* Date: 2024/5/15* java 内置的延迟队列* 服务器重启后,数据全部消失,怕宕机* 他是无界队列 可以一直放 有可能导致内存满的问题* 所以不宜处理 任务比较多的业务* 用来处理 任务少并不是很重要的数据**/
@Component
@Slf4j
@Order(3)
public class DelayQueueUtil<T> implements CommandLineRunner {private final DelayQueue<DelayTask<T>> delayQueue = new DelayQueue<>();private volatile boolean running = true;@Autowiredprivate ThreadPoolTaskExecutor taskExecutor;@AutowiredAicCdJob aicCdJob;/*** 加入到延时队列中* @param task*/public void put(DelayTask<T> task) {// log.info("加入延时任务时间:"+LocalDateTime.now()+",加入延时任务:"+task);delayQueue.put(task);}/*** 取消延时任务* @param task* @return*/public boolean remove(DelayTask<T> task) {//log.info("取消延时任务时间:"+LocalDateTime.now()+",取消延时任务:{}", task);return delayQueue.remove(task);}/*** 取消延时任务* @param taskid* @return*/public boolean remove(T taskid) {return remove(new DelayTask<>(taskid, 0));}//初始化延迟线程@Overridepublic void run(String... args) {//log.info("初始化延时队列");taskExecutor.execute(this::executeThread);}/*** 延时任务执行线程*/public void executeThread() {while (running) {try {DelayTask<T> task = delayQueue.take();processTask(task);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}}/*** 内部执行延时任务* @param task*/public void processTask(DelayTask<T> task) {//  log.info("执行延时任务时间:"+LocalDateTime.now()+"【参数】:"+task);if(task.getData() instanceof SkeAirCdRealtimeData){aicCdJob.aicCdRealTimeDatAll();}else if(task.getData() instanceof String){System.out.println(task.getData());}// 根据task中的data自定义数据来处理相关逻辑,例如 if (task.getData() instanceof XXX) {}}/*** 停止延时队列*/public void stop() {running = false;Thread.currentThread().interrupt();taskExecutor.shutdown();}@PreDestroypublic void onDestroy() {stop();}}

调用

    @AutowiredDelayQueueUtil delayQueueUtil;@GetMapping("index18")@ApiOperation(value = "测试延迟任务")public R index18(){for (int i=0;i<=20;i++){delayQueueUtil.put(new DelayTask<>("第"+i+"次", 2));}//delayQueueUtil.put(new DelayTask<>(new SkeAirCdRealtimeData(), 1));return R.success();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/17258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala的简单学习二

一集合 1.1 Java集合 1.在scala创建Java集合需要导入java.util包 2.不能使用scala中遍历迭代器的方法遍历Java集合 3.使用下标索引遍历Java集合 4.list集合中&#xff0c;add是添加元素(可以指定下表索引插入)&#xff0c;get是通过下标索引获取元素&#xff0c;size是获取…

【Python】 如何在Python中设置环境变量?

基本原理 在Python中&#xff0c;环境变量是一种存储系统或应用程序配置信息的方式&#xff0c;它们可以被操作系统或应用程序访问。环境变量通常用于配置应用程序的行为&#xff0c;例如指定数据库的连接字符串、API密钥、文件路径等。 Python提供了几种方法来设置和访问环境…

心电信号降噪方法(滤波器/移动平均/小波等,MATLAB环境)

对于一个正常的、完整的心动周期&#xff0c;对应的心电图波形如下图所示&#xff0c;各个波形都对应着心脏兴奋活动的生理过程&#xff0c;包含P波&#xff0c;PR段&#xff0c;QRS波群&#xff0c;ST段&#xff0c;T波&#xff0c;U波。 &#xff08;1&#xff09;P波心电图中…

OpenBMC相关的网站

openbmc官方网站 https://github.com/openbmchttps://github.com/openbmc Dashboard [Jenkins]https://jenkins.openbmc.org/ https://gerrit.openbmc.org/Gerrit Code Reviewhttps://gerrit.openbmc.org/ Searchhttps://grok.openbmc.org/ openbmc参考网站 https://www.c…

R实验 正交试验设计与一元线性回归分析

实验目的&#xff1a; 掌握正交试验设计记号的意义&#xff1b;掌握正交试验设计的直观分析和方差分析&#xff1b;掌握一元线性回归模型的相关概念&#xff1b;掌握最小二乘法的思想&#xff1b;掌握一元线性回归方程的显著性检验和预测。 实验内容&#xff1a; &#xff11;…

C++ day1 作业练习

整理思维导图 定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream> #include <cstring>using namespace std; namespace my_space {string s1; }void show() {cout<…

NASA数据集——严格校准的臭氧(O3)、甲醛(HCHO)、二氧化碳(CO2)和甲烷(CH4)混合比,以及包括三维风在内的气象数据

Alpha Jet Atmopsheric eXperiment Meteorological Measurement System (MMS) Data 阿尔法喷气式大气实验气象测量系统&#xff08;MMS&#xff09;数据 简介 Alpha Jet Atmospheric eXperiment (AJAX) 是美国国家航空航天局艾姆斯研究中心与 H211, L.L.C. 公司的合作项目&a…

C#面:当一个线程进入一个对象的方法后,其它线程是否可以进入该对象的方法?

一个线程在访问一个对象的一个synchronized方法时&#xff1a; 另一个线程可以同时访问这个对象的非同步方法。另一个线程不可以同时访问这个对象的普通同步方法。另一个线程可以同时访问这个对象的静态同步方法 &#xff0c;即static synchronized修饰的方法 。另一个线程不可…

win10 cmake vs2019 qt opencv contrib 下载 编译 提供编译好的全套文件下载

本文意在提供 win10系统下 使用 cmake-gui 配置 opencv源码 再使用vs2019编译的全套过程 为什么是win10系统? 主要提供给使用pc端的人使用,例如工厂员工 或 上课教学 还可以是什么系统? 当然这一切也可以在arm上操作 例如一块stm32及其配套的硬件 装在无人机上 图像中就…

【Python】 去除空白字符的艺术:Python中的字符串修剪技巧

基本原理 在Python编程中&#xff0c;经常会遇到需要去除字符串两端空白字符&#xff08;也称为“修剪”&#xff09;的情况。空白字符包括空格、制表符、换行符等。Python提供了多种方法来处理字符串中的空白字符&#xff0c;其中最常见的是使用字符串的strip()方法。 strip…

SpringSecurity6从入门到实战之引言和基本概念

SpringSecurity6从入门到实战之引言和基本概念 前言 在当今数字化时代&#xff0c;随着网络应用的日益普及&#xff0c;保护用户数据和系统安全变得至关重要。作为Java开发社区的中坚力量&#xff0c;Spring框架提供了一整套解决方案来构建企业级应用程序。然而&#xff0c;随…

APM2.8飞控

ArduPilotMega 主控可应用于 固定翼、直升机、多旋翼、地面车辆 APM2.8飞控供电有两种 1.电流计供电&#xff0c; 2.带BEC&#xff08;稳压功能&#xff09;的电调供电 ArduPilotMega 内部的硬件结构图&#xff1a; 调试时&#xff0c;不要使用向导&#xff0c;由于向导功能不…

Linux中的SCP:有你,一切都不遥远

引言 在Linux系统中&#xff0c;文件传输是一个常见的任务。SCP&#xff08;Secure Copy Protocol&#xff09;命令提供了一种安全的方式来在本地和远程计算机之间复制文件。本文将详细介绍SCP命令的使用方法&#xff0c;并提供一些实用的示例以及故障排除指南。 SCP命令简介…

vue组件通讯$parent和$children获取单签组件的⽗组件和当前组件的⼦组件的例子

在 Vue 中&#xff0c;$parent 和 $children 是实例属性&#xff0c;允许你访问组件的父组件和子组件。但是&#xff0c;请注意&#xff0c;这些属性主要用于在开发过程中进行调试和临时访问&#xff0c;并不推荐在正常的组件通信中使用&#xff0c;因为它们破坏了组件的封装性…

React Native 之 Linking(链接)(十五)

URL Scheme是什么 URL Scheme是一种机制&#xff0c;主要用于在移动应用程序中打开另一个应用程序或执行特定操作。 定义与原理&#xff1a; URL Scheme允许应用程序通过特定的URL格式与其他应用程序进行交互。 它通过在应用程序中注册一个自定义的URL Scheme&#xff0c;并在…

[GDB] GDB调试

目录 一 简介 二 功能: 三 命令: 四 调试准备: 五 开始调试: 5.1 添加断点&#xff1a; 5.2 条件编译 5.3 断点查看 5.4 断点删除: 5.5 查看源码 5.6 单步调试(逐过程)&#xff1a; 5.7 断点调试: 5.8 单步跟踪(逐语句): 5.9 调试过程&#xff1a; 5.9.1 开始调…

在CentOS 8上卸载与安装MySQL 8的详细步骤

关键词&#xff1a;MySQL 8安装、CentOS 8、YUM源配置、卸载MySQL、MySQL残留文件删除、首次登录MySQL临时密码、服务状态检查、MySQL社区服务器 阅读建议&#xff1a;本文适合需要在CentOS 8操作系统上部署最新MySQL 8数据库的系统管理员或开发者阅读。文中步骤简洁清晰&#…

Spring (23)如何在Spring中配置数据源

在Spring中配置数据源是一个基本且重要的任务&#xff0c;特别是在构建依赖于数据库操作的应用程序时。数据源&#xff08;DataSource&#xff09;是数据库连接的工厂&#xff0c;Spring通过数据源抽象简化了数据库连接的管理。配置数据源通常涉及定义一个或多个DataSourcebean…

ssm145基于java的电脑硬件库存管理系统+jsp

电脑硬件库存管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对电脑硬件库存信息管理混乱&…

【设计模式】创建型-抽象工厂模式

前言 在软件开发领域&#xff0c;设计模式是一种被广泛接受的解决方案&#xff0c;用于解决特定问题并提供可维护和可扩展的代码结构。抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是其中之一&#xff0c;它提供了一种方法来创建一系列相关或相互依赖的对象…