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

Java 并发编程 - Delay(Delayed 概述、Delayed 实现、Delayed 使用、Delay 缓存实现、Delayed 延迟获取数据实现)

一、Delayed 概述

public interface Delayed extends Comparable<Delayed> {long getDelay(TimeUnit unit);
}
  1. Delayed 用于表示在给定延迟时间之后应该被处理的对象

  2. 核心方法 getDelay 用于返回指定时间单位的剩余的延迟时间,正数表示延迟尚未到期,0 或负数表示延迟已到期

  3. Delay 继承了 Comparable<Delayed> 接口,需要同时实现 compareTo 方法

  4. Delayed 通常与 DelayQueue 结合使用


二、Delayed 实现

  • MyDelayedTask.java
public class MyDelayedTask implements Delayed {private final long baseTime;  // 基准时间,通常为创建时间private final long delay;     // 延迟时长private final TimeUnit unit;  // 时间单位public MyDelayedTask(long delay, TimeUnit unit) {this.baseTime = System.nanoTime();this.delay = delay;this.unit = unit;}@Overridepublic long getDelay(TimeUnit requestedUnit) {// 计算已经过去的时间long elapsed = System.nanoTime() - baseTime;// 计算总延迟的纳秒数long totalDelayNanos = unit.toNanos(delay);// 计算剩余延迟long remaining = totalDelayNanos - elapsed;// 转换为请求的时间单位return requestedUnit.convert(remaining, TimeUnit.NANOSECONDS);}@Overridepublic int compareTo(Delayed other) {// 统一转换为纳秒进行比较long myDelay = this.getDelay(TimeUnit.NANOSECONDS);long otherDelay = other.getDelay(TimeUnit.NANOSECONDS);return Long.compare(myDelay, otherDelay);}
}
  • SimpleDelayedTask.java
public class SimpleDelayedTask implements Delayed {private final String data;private final long startTime;private final long delayNanos;public SimpleDelayedTask(String data, long delay, TimeUnit unit) {this.data = data;this.startTime = System.nanoTime();this.delayNanos = unit.toNanos(delay);}@Overridepublic long getDelay(TimeUnit unit) {// 计算过去的延迟时间long elapsed = System.nanoTime() - startTime;// 计算剩余的延迟时间long remaining = delayNanos - elapsed;// 转换为指定的时间单位return unit.convert(remaining, TimeUnit.NANOSECONDS);}@Overridepublic int compareTo(Delayed other) {if (this == other) return 0;// 统一转换为纳秒进行比较long thisDelay = this.getDelay(TimeUnit.NANOSECONDS);long otherDelay = other.getDelay(TimeUnit.NANOSECONDS);return Long.compare(thisDelay, otherDelay);}public String getData() {long delay = this.getDelay(TimeUnit.NANOSECONDS);if (delay <= 0) {return data;} else {return null;}}
}

三、Delayed 使用

1、基本使用
SimpleDelayedTask simpleDelayedTask = new SimpleDelayedTask("test content", 3, TimeUnit.SECONDS);while (true) {String data = simpleDelayedTask.getData();if (data != null) {System.out.println("任务就绪,执行任务,获取到数据: " + data);break;} else {System.out.println("任务还未就绪,等待中...");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}
}
# 输出结果任务还未就绪,等待中...
任务还未就绪,等待中...
任务还未就绪,等待中...
任务还未就绪,等待中...
任务还未就绪,等待中...
任务还未就绪,等待中...
任务就绪,执行任务,获取到数据: test content
SimpleDelayedTask task1 = new SimpleDelayedTask("task1", 2, TimeUnit.SECONDS);
SimpleDelayedTask task2 = new SimpleDelayedTask("task2", 4, TimeUnit.SECONDS);
SimpleDelayedTask task3 = new SimpleDelayedTask("task3", 1, TimeUnit.SECONDS);boolean task1Done = false;
boolean task2Done = false;
boolean task3Done = false;while (!task1Done || !task2Done || !task3Done) {if (!task1Done) {String data = task1.getData();if (data != null) {System.out.println("任务 1 完成: " + data);task1Done = true;}}if (!task2Done) {String data = task2.getData();if (data != null) {System.out.println("任务 2 完成: " + data);task2Done = true;}}if (!task3Done) {String data = task3.getData();if (data != null) {System.out.println("任务 3 完成: " + data);task3Done = true;}}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
}System.out.println("所有任务完成");
# 输出结果任务 3 完成: task3
任务 1 完成: task1
任务 2 完成: task2
所有任务完成
2、结合 DelayQueue 使用
DelayQueue<SimpleDelayedTask> delayQueue = new DelayQueue<>();delayQueue.add(new SimpleDelayedTask("test content1", 2, TimeUnit.SECONDS));
delayQueue.add(new SimpleDelayedTask("test content2", 4, TimeUnit.SECONDS));
delayQueue.add(new SimpleDelayedTask("test content3", 1, TimeUnit.SECONDS));while (!delayQueue.isEmpty()) {try {SimpleDelayedTask simpleDelayedTask = delayQueue.take();System.out.println("任务就绪,执行任务,获取到数据: " + simpleDelayedTask.getData());} catch (InterruptedException e) {e.printStackTrace();}
}
# 输出结果任务就绪,执行任务,获取到数据: test content3
任务就绪,执行任务,获取到数据: test content1
任务就绪,执行任务,获取到数据: test content2

四、Delay 缓存实现

1、基本实现
  1. Delayed 实现,CacheItem.java
public class CacheItem implements Delayed {private final String data;private final long startTime;private final long delayNanos;public CacheItem(String data, long delay, TimeUnit unit) {this.data = data;this.startTime = System.nanoTime();this.delayNanos = unit.toNanos(delay);}@Overridepublic long getDelay(TimeUnit unit) {long elapsed = System.nanoTime() - startTime;long remaining = delayNanos - elapsed;return unit.convert(remaining, TimeUnit.NANOSECONDS);}@Overridepublic int compareTo(Delayed other) {if (this == other) return 0;// 统一转换为纳秒进行比较long thisDelay = this.getDelay(TimeUnit.NANOSECONDS);long otherDelay = other.getDelay(TimeUnit.NANOSECONDS);return Long.compare(thisDelay, otherDelay);}public String getData() {long delay = this.getDelay(TimeUnit.NANOSECONDS);if (delay <= 0) {return null;} else {return data;}}
}
  1. Test
CacheItem cacheItem = new CacheItem("test content", 3, TimeUnit.SECONDS);while (true) {String data = cacheItem.getData();if (data != null) {System.out.println("缓存未过期,获取到数据: " + data);} else {System.out.println("缓存已过期");break;}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
}
# 输出结果缓存未过期,获取到数据: test content
缓存未过期,获取到数据: test content
缓存未过期,获取到数据: test content
缓存未过期,获取到数据: test content
缓存未过期,获取到数据: test content
缓存未过期,获取到数据: test content
缓存已过期
2、缓存管理器
  1. SimpleCacheManager.java
public class SimpleCacheManager {private final Map<String, CacheItem> cacheItemMap = new ConcurrentHashMap<>();public void put(String key, String value, long ttl, TimeUnit unit) {cacheItemMap.put(key, new CacheItem(value, ttl, unit));System.out.println("缓存设置: " + key + " -> " + value + " (TTL: " + ttl + " " + unit + ")");}public void remove(String key) {cacheItemMap.remove(key);System.out.println("缓存移除: " + key);}public String get(String key) {CacheItem item = cacheItemMap.get(key);if (item != null) {return item.getData();}return null;}public void clean() {cacheItemMap.values().removeIf(item -> item.getDelay(TimeUnit.NANOSECONDS) <= 0);}
}
  1. Test
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();simpleCacheManager.put("user:A", "用户 A 信息", 3, TimeUnit.SECONDS);
simpleCacheManager.put("config:app", "应用配置", 5, TimeUnit.SECONDS);for (int i = 0; i < 8; i++) {System.out.println("=== 第 " + (i + 1) + " 次查询 ===");String userData = simpleCacheManager.get("user:A");System.out.println("user:A -> " + userData);String configData = simpleCacheManager.get("config:app");System.out.println("config:app -> " + configData);simpleCacheManager.clean();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
}
# 输出结果缓存设置: user:A -> 用户 A 信息 (TTL: 3 SECONDS)
缓存设置: config:app -> 应用配置 (TTL: 5 SECONDS)
=== 第 1 次查询 ===
user:A -> 用户 A 信息
config:app -> 应用配置
=== 第 2 次查询 ===
user:A -> 用户 A 信息
config:app -> 应用配置
=== 第 3 次查询 ===
user:A -> 用户 A 信息
config:app -> 应用配置
=== 第 4 次查询 ===
user:A -> null
config:app -> 应用配置
=== 第 5 次查询 ===
user:A -> null
config:app -> 应用配置
=== 第 6 次查询 ===
user:A -> null
config:app -> null
=== 第 7 次查询 ===
user:A -> null
config:app -> null
=== 第 8 次查询 ===
user:A -> null
config:app -> null
3、可重置缓存时间
  1. Delayed 实现,MyCacheItem.java
public class MyCacheItem implements Delayed {private final String data;private long startTime;private long delayNanos;public MyCacheItem(String data, long delay, TimeUnit unit) {this.data = data;this.startTime = System.nanoTime();this.delayNanos = unit.toNanos(delay);}@Overridepublic long getDelay(TimeUnit unit) {long elapsed = System.nanoTime() - startTime;long remaining = delayNanos - elapsed;return unit.convert(remaining, TimeUnit.NANOSECONDS);}@Overridepublic int compareTo(Delayed other) {if (this == other) return 0;// 统一转换为纳秒进行比较long thisDelay = this.getDelay(TimeUnit.NANOSECONDS);long otherDelay = other.getDelay(TimeUnit.NANOSECONDS);return Long.compare(thisDelay, otherDelay);}public String getData() {long delay = this.getDelay(TimeUnit.NANOSECONDS);if (delay <= 0) {return null;} else {return data;}}public boolean resetDelay(long delay, TimeUnit unit) {if (getDelay(TimeUnit.NANOSECONDS) <= 0) {return false;}// 重置缓存时间this.startTime = System.nanoTime();this.delayNanos = unit.toNanos(delay);return true;}
}
  1. Test
MyCacheItem myCacheItem = new MyCacheItem("test content", 3, TimeUnit.SECONDS);int queryCount = 0;while (true) {// 在第 3 次查询时,重置缓存过期时间为 5 秒queryCount++;System.out.println("=== 第 " + (queryCount) + " 次查询 ===");if (queryCount == 3) {System.out.println("重置缓存过期时间为 5 秒");myCacheItem.resetDelay(5, TimeUnit.SECONDS);}String data = myCacheItem.getData();if (data != null) {System.out.println("缓存未过期,获取到数据: " + data);} else {System.out.println("缓存已过期");break;}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
}
# 输出结果===1 次查询 ===
缓存未过期,获取到数据: test content
===2 次查询 ===
缓存未过期,获取到数据: test content
===3 次查询 ===
重置缓存过期时间为 5 秒
缓存未过期,获取到数据: test content
===4 次查询 ===
缓存未过期,获取到数据: test content
===5 次查询 ===
缓存未过期,获取到数据: test content
===6 次查询 ===
缓存未过期,获取到数据: test content
===7 次查询 ===
缓存未过期,获取到数据: test content
===8 次查询 ===
缓存未过期,获取到数据: test content
===9 次查询 ===
缓存未过期,获取到数据: test content
===10 次查询 ===
缓存未过期,获取到数据: test content
===11 次查询 ===
缓存未过期,获取到数据: test content
===12 次查询 ===
缓存未过期,获取到数据: test content
===13 次查询 ===
缓存已过期

五、Delayed 延迟获取数据实现

  1. Delayed 实现,MakeTask.java
public class MakeTask implements Delayed {private final String data;private final long startTime;private final long delayNanos;public MakeTask(String data, long delay, TimeUnit unit) {this.data = data;this.startTime = System.nanoTime();this.delayNanos = unit.toNanos(delay);}@Overridepublic long getDelay(TimeUnit unit) {long elapsed = System.nanoTime() - startTime;long remaining = delayNanos - elapsed;return unit.convert(remaining, TimeUnit.NANOSECONDS);}@Overridepublic int compareTo(Delayed other) {if (this == other) return 0;// 统一转换为纳秒进行比较long thisDelay = this.getDelay(TimeUnit.NANOSECONDS);long otherDelay = other.getDelay(TimeUnit.NANOSECONDS);return Long.compare(thisDelay, otherDelay);}public String getData() {long delay = this.getDelay(TimeUnit.NANOSECONDS);if (delay <= 0) {return data;} else {return null;}}
}
  1. Test
MakeTask makeTask = new MakeTask("稿子", 3, TimeUnit.SECONDS);while (true) {String data = makeTask.getData();if (data != null) {System.out.println("制作完成,获取到道具: " + data);break;} else {System.out.println("还未制作完成,等待中...");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}
}
# 输出结果还未制作完成,等待中...
还未制作完成,等待中...
还未制作完成,等待中...
还未制作完成,等待中...
还未制作完成,等待中...
还未制作完成,等待中...
制作完成,获取到道具: 稿子
http://www.dtcms.com/a/582707.html

相关文章:

  • 深圳专业网站优化公司报价线上广告投放收费标准
  • 如何建网站服务器广州贸易网站
  • 单板电源设计
  • 个人备案网站 内容企业网站 空间
  • PVE 9 显卡直通 外显 一个案例
  • h5是什么网站上面做的后端开发工作内容
  • 用滑动窗口法降噪
  • 网站建设与运营意义商标设计图片
  • 网站模板下载软件成都网站建设服务商
  • 整体设计 全面梳理复盘 之22 九宫格框架搭建与一体化开发环境设计 编程 之1
  • 数据库参数OPTIMIZER_INDEX_COST_ADJ的一段故事
  • 江西中联建设集团有限公司网站百度网站开发合同范本
  • 西安代做毕业设计网站黑龙江省建设会计协会网站
  • 网站建设7大概要多久做家装的网站有哪些内容
  • 网站description是指什么易天时代网站建设
  • 【期末网页设计作业】HTML+CSS 唐诗学习网站主题的开发(附源码与效果演示)
  • 如何做平台推广seo如何快速排名百度首页
  • zencart网站qq企业邮箱官网
  • 想要极度深入了解一个研究方向,是否要读完所有文献?
  • 三亚网站开发公司温州论坛吧
  • 多人协作Git开发流程指南
  • seo博客网站青岛网络推广公司哪家好
  • 口碑好的建筑设备监控管理系统服务商排名
  • 新手如何做企业网站海南网红打卡旅游景点
  • 济南网站排名推广销售外包服务
  • 学习日报 20251107|Nacos基础认识
  • QPainter
  • 深入评测openEuler 24.03 LTS SP2:在云原生时代构筑高性能的应用与实战操作
  • 网站建设网页链接wordpress flash加载插件
  • wordpress积分阅读成都自动seo