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

【Java】DelayQueue

一,概述

本文简单介绍下延迟队列,顾名思义,加入队列的元素具备延时出队的特征,在诸如延迟消息时可简单使用,本文笔者以学习心态简单介绍下此数据结构。

DelayQueue实现类图如下

DelayQueue实现Queue接口,内部保存一个优先级队列,新加入队列的元素必须实现Delay接口,实现getDelay和compareTo方法,以满足优先级队列排序,以及出队延迟计算。

二,实例

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class DelayQueueMain {public static void main(String[] args) throws InterruptedException {DelayQueue<Message> queue = new DelayQueue<>();//创建一个消费者线程new Thread(() -> {try {System.out.println("Consumer Thread Create.");while (true) {Message message = queue.take();message.action.run();}} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();//生产者for (int i = 0; i < 10; i++) {Message message = new Message((10 - i) * 200, i);queue.add(message);Thread.sleep(100);}}private static class Message implements Delayed {private final long createTime;private final long delayMs;private final long id;private final Runnable action = new Runnable() {@Overridepublic void run() {//简单demo,打印id即可System.out.println("invoke Message Id=" + id + ", DelayMs=" + delayMs);}};public Message(long delayMs, long id) {this.id = id;this.delayMs = delayMs;this.createTime = System.currentTimeMillis();}@Overridepublic long getDelay(TimeUnit unit) {return this.createTime + this.delayMs - System.currentTimeMillis();}@Overridepublic int compareTo(Delayed o) {long selfDelay = getDelay(TimeUnit.MILLISECONDS);long otherDelay = o.getDelay(TimeUnit.MILLISECONDS);if (selfDelay == otherDelay) {return 0;}return selfDelay > otherDelay ? 1 : -1;}}
}

输出如下

从上述结果可知,生产者加入队列的延迟消息,在消费者处如预期输出。

三,原理

优先级队列中,存放的元素实现了Delayed接口,通过getDelay可判断元素的优先级,delay小的优先在队列前端。

生产者offer

很简单,往队列中放一个元素,如果为空,则通过condition通知到消费者

消费者take

1,队列为空,通过condition等待

2,3,获得优先级队列第一个元素,并且计算当前getDelay值,小于0则出队,跳出for循环,否则继续超时await

http://www.xdnf.cn/news/9246.html

相关文章:

  • LangGraph(七)——Workflows
  • 基于物联网(IoT)的电动汽车(EVs)智能诊断
  • Java组合、聚合与关联:核心区别解析
  • AWS WebRTC:获取信令服务节点和ICE服务节点
  • 深度解读 Qwen3 大语言模型的关键技术
  • 【Elasticsearch】ingest对于update操作起作用吗?
  • Android15 Camera Hal设置logLevel控制日志输出
  • vue2使用el-tree实现两棵树间节点的拖拽复制
  • LeetCode 2894.分类求和并作差:数学O(1)一行解决
  • Java提取markdown中的表格
  • go并发与锁之sync.Mutex入门
  • 国11阶乘约数-质因数分解
  • C/C++的OpenCV的锐化
  • vue 前端请求跨域解决办法
  • 九级融智台阶与五大要素协同的量子化解析
  • MGAug:图像变形潜空间中的多模态几何增强|文献速递-深度学习医疗AI最新文献
  • 端口 3389 服务 ms - wbt - server 漏洞修复方法
  • 你的网站真的安全吗?如何防止网站被攻击?
  • 联软科技统一安全工作空间:零信任架构下的远程办公数据安全守护者
  • 每天掌握一个Linux命令 - sqlite3
  • EasyRTC嵌入式SDK音视频实时通话助力WebRTC技术与智能硬件协同发展
  • Nginx 配置文件深度解析:从核心模块到扩展机制
  • WPF【11_4】WPF实战-重构与美化(MVVM 架构)
  • 【elasticsearch 7 或8 的安装及配置SSL 操作指引】
  • 【Doris入门】Doris初识:分布式分析型数据库的核心价值与架构解析
  • 关于空调温度控制仿真模型的详细技术文档,包含数学模型、Python实现和系统分析
  • 引导者之歌------------嵌入式软件面试问题集成
  • 修改SpringBootApplication类的入参后,引用外部yml的启动命令要修改
  • ArcGIS Pro 3.4 二次开发 - 地理处理
  • 计算机网络练习题