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

【SpringBoot】调度和执行定时任务--DelayQueue (附demo)

DelayQueue 是 Java 中 java.util.concurrent 包的一部分,它是一个无界阻塞队列,其中的元素只能在其到期时才能被取出。DelayQueue 是一个泛型类,要求队列中的元素实现 Delayed 接口。

1. Delayed 接口

要使用 DelayQueue,首先需要实现 Delayed 接口。Delayed 接口继承自 Comparable 接口,要求实现以下两个方法:

  • long getDelay(TimeUnit unit): 返回剩余的延迟时间。
  • int compareTo(Delayed o): 比较两个延迟对象的顺序。

2. 创建一个 Delayed 元素

下面是一个简单的实现 Delayed 接口的类:

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class DelayedElement implements Delayed {private final long delayTime;private final long expireTime;private final String message;public DelayedElement(long delayTime, String message) {this.delayTime = delayTime;this.expireTime = System.currentTimeMillis() + delayTime;this.message = message;}@Overridepublic long getDelay(TimeUnit unit) {long diff = expireTime - System.currentTimeMillis();return unit.convert(diff, TimeUnit.MILLISECONDS);}@Overridepublic int compareTo(Delayed o) {if (this.expireTime < ((DelayedElement) o).expireTime) {return -1;}if (this.expireTime > ((DelayedElement) o).expireTime) {return 1;}return 0;}public String getMessage() {return message;}
}

3. 使用 DelayQueue

创建一个 DelayQueue 并添加 Delayed 元素:

import java.util.concurrent.DelayQueue;public class DelayQueueExample {public static void main(String[] args) throws InterruptedException {DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();// 添加延迟元素到队列中delayQueue.put(new DelayedElement(5000, "Message 1")); // 5秒延迟delayQueue.put(new DelayedElement(10000, "Message 2")); // 10秒延迟delayQueue.put(new DelayedElement(15000, "Message 3")); // 15秒延迟// 取出元素while (!delayQueue.isEmpty()) {DelayedElement element = delayQueue.take(); // 阻塞,直到有元素到期System.out.println("Received: " + element.getMessage());}}
}

4. 常用方法

DelayQueue 提供了一些常用的方法:

  • boolean add(E e): 添加元素到队列中。
  • boolean offer(E e): 尝试添加元素到队列中。
  • void put(E e): 添加元素到队列中,如果队列已满则阻塞。
  • E take(): 取出并移除队列头部的元素,如果没有元素到期则阻塞。
  • E poll(): 取出并移除队列头部的元素,如果没有元素到期返回 null
  • E peek(): 获取队列头部的元素,但不移除,如果没有元素到期返回 null
  • int size(): 返回队列中元素的数量。

5. 示例:使用 DelayQueue 实现延迟任务调度

下面是一个使用 DelayQueue 实现延迟任务调度的示例:

import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class DelayQueueScheduler {private final DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();private final ExecutorService executor = Executors.newSingleThreadExecutor();public DelayQueueScheduler() {executor.execute(() -> {try {while (true) {DelayedElement element = delayQueue.take();System.out.println("Executing task: " + element.getMessage());}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}public void scheduleTask(long delay, String message) {delayQueue.put(new DelayedElement(delay, message));}public void shutdown() {executor.shutdown();}public static void main(String[] args) throws InterruptedException {DelayQueueScheduler scheduler = new DelayQueueScheduler();scheduler.scheduleTask(5000, "Task 1"); // 5秒后执行scheduler.scheduleTask(10000, "Task 2"); // 10秒后执行scheduler.scheduleTask(15000, "Task 3"); // 15秒后执行Thread.sleep(20000); // 主线程等待20秒scheduler.shutdown();}
}

6. 注意事项

  • DelayQueue 是无界队列,因此在使用时要小心避免内存泄漏。
  • DelayQueue 中的元素必须实现 Delayed 接口,否则无法正常工作。
  • DelayQueuetake 方法是阻塞的,会一直等待直到有元素到期。

通过这些详细的用法和示例,你可以了解如何在Java中使用 DelayQueue 来实现延迟任务调度。根据具体需求选择合适的调度方法和处理策略。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JavaScript --函数的作用域(全局和局部)
  • kafka 之 本地部署单机版
  • [java][SSM]整合Mybatis3、Spring4 和 SpringMVC4 的步骤
  • 【zabbix监控软件(配置及常用键值)】
  • it基础软件运维管理:从操作系统到数据库,再到中间件和应用系统
  • 使用Docker快速安装和运行Elasticsearch
  • 【Android】SurfaceFlinger Dumpsys信息分析
  • openVX加速-结合AI推理引擎代码示例
  • 集群聊天服务器项目【C++】(三)muduo库的简单介绍
  • 网页模板该怎么选
  • MVC 控制器
  • Java | Leetcode Java题解之第401题二进制手表
  • yolov8 rect batch_shapes 672 图像大小变化
  • PHP智驭未来悦享生活智慧小区物业管理小程序系统源码
  • Java的发展史与前景
  • 【Leetcode】101. 对称二叉树
  • 【node学习】协程
  • ES6系统学习----从Apollo Client看解构赋值
  • Git学习与使用心得(1)—— 初始化
  • 订阅Forge Viewer所有的事件
  • 构建二叉树进行数值数组的去重及优化
  • 前端面试之CSS3新特性
  • 微信支付JSAPI,实测!终极方案
  • 一些css基础学习笔记
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 阿里云服务器购买完整流程
  • 第二十章:异步和文件I/O.(二十三)
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​低代码平台的核心价值与优势
  • ​你们这样子,耽误我的工作进度怎么办?
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #QT(串口助手-界面)
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (02)Unity使用在线AI大模型(调用Python)
  • (10)ATF MMU转换表
  • (13)Hive调优——动态分区导致的小文件问题
  • (floyd+补集) poj 3275
  • (k8s)Kubernetes本地存储接入
  • (二)Linux——Linux常用指令
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)setTimeout 和 setInterval 的区别
  • (转)visual stdio 书签功能介绍
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .jks文件(JAVA KeyStore)
  • .NET MVC之AOP
  • .NET中GET与SET的用法
  • @Autowired和@Resource的区别
  • @Service注解让spring找到你的Service bean