程序包 com.iohao.game.common.kit.concurrent.timer.delay
package com.iohao.game.common.kit.concurrent.timer.delay
工具相关 - 轻量可控的延时任务,任务到达指定时间后会执行、任务可取消、任务可增加或减少延时时间、任务可被覆盖、可设置任务监听回调。
轻量可控的延时任务 - 简介
我们知道,在 TaskKit
中,提供了一个任务、时间、延时监听、超时监听 ...等相结合的一个工具模块,通过 runOnce 可以执行一些延时任务;
但有时,我们需要一些可控的延时任务,也就是延时时间可以根据后续的业务来变化,比如增加或减少延时的时间、取消任务 ...等可控的操作。
轻量可控的延时任务 - 特点
1. 单一职责原则 2. 任务到达指定时间后会执行 3. 任务可取消 4. 任务可被覆盖 5. 任务可增加、减少延时的时间 6. 可设置任务监听回调 7. 内部使用 Netty HashedWheelTimer,轻松支持百万任务。for example
public class DelayTaskTest {
@Test
public void runDelayTask() {
// ---------------演示 - 延时任务---------------
// 1 秒后执行延时任务
DelayTaskKit.of(() -> {
log.info("1 秒后执行的延时任务");
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
}
@Test
public void plusDelayTime() {
// ---------------演示 - 增加延时时间---------------
long timeMillis = System.currentTimeMillis();
DelayTask delayTask = DelayTaskKit.of(() -> {
long value = System.currentTimeMillis() - timeMillis;
log.info("增加延时时间,最终 {} ms 后,执行延时任务", value);
// Assert.assertTrue(value > 1490);
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
delayTask.plusTimeMillis(500); // 增加 0.5 秒的延时
// 最终 1.5 秒后执行延时任务
}
@Test
public void minusDelayTime() {
// ---------------演示 - 减少延时时间---------------
long timeMillis = System.currentTimeMillis();
// 1 秒后执行延时任务
DelayTask delayTask = DelayTaskKit.of(() -> {
long value = System.currentTimeMillis() - timeMillis;
log.info("减少延时时间,最终 {} ms 后,执行延时任务", value);
// Assert.assertTrue(value < 510);
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
delayTask.minusTimeMillis(500); // 减少 0.5 秒的延时时间
// 最终 0.5 秒后执行延时任务
}
@Test
public void coverDelayTask() throws InterruptedException {
// ---------------演示 - 覆盖延时任务---------------
String taskId = "1";
DelayTaskKit.of(taskId, () -> log.info("执行任务 - 1"))
.plusTime(Duration.ofSeconds(2)) // 增加 2 秒的延时
.task(); // 启动任务
TimeUnit.MILLISECONDS.sleep(500);
long timeMillis = System.currentTimeMillis();
// 因为 taskId 相同,所以会覆盖之前的延时任务
DelayTask delayTask = DelayTaskKit.of(taskId, () -> {
long value = System.currentTimeMillis() - timeMillis;
log.info("执行任务 - 2,最终 {} ms 后,执行延时任务", value);
// Assert.assertTrue(value > 990);
})
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
}
@Test
public void cancelDelayTask() throws InterruptedException {
// ---------------演示 - 取消延时任务,通过 DelayTask 来取消---------------
DelayTask delayTask = DelayTaskKit.of(() -> {
log.info("取消 - 延时任务");
})
.plusTime(Duration.ofSeconds(2)) // 增加 2 秒的延时
.task(); // 启动任务
log.info("0.5 秒后, 因为满足某个业务条件, 不想执行定时任务了");
TimeUnit.MILLISECONDS.sleep(500);
delayTask.isActive(); // true
delayTask.cancel(); // 取消任务
delayTask.isActive(); // false
// -----------演示 - 取消延时任务,通过 taskId 来取消-----------
String taskId = "1";
// 在创建延时任务时,设置 taskId
DelayTaskKit.of(taskId, () -> log.info("通过 taskId 取消 - 延时任务"))
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.task(); // 启动任务
log.info("0.5 秒后, 因为满足某个业务条件, 不想执行定时任务了");
TimeUnit.MILLISECONDS.sleep(500);
DelayTaskKit.cancel(taskId); // 通过 taskId 取消任务
}
@Test
public void optionalDelayTask() {
// ---------------演示 - 查找延时任务---------------
String newTaskId = "1";
DelayTaskKit.of(newTaskId, () -> log.info("hello DelayTask"))
// 2.5 秒后执行延时任务。(这里演示添加延时时间的两个方法)
.plusTime(Duration.ofSeconds(1)) // 增加 1 秒的延时
.plusTime(Duration.ofMillis(1000)) // 增加 1 秒的延时
.plusTimeMillis(500) // 增加 0.5 秒的延时
.task(); // 启动任务
// 在后续的业务中,可以通过 taskId 查找该延时任务
Optional<DelayTask> optionalDelayTask = DelayTaskKit.optional(newTaskId);
if (optionalDelayTask.isPresent()) {
DelayTask delayTask = optionalDelayTask.get();
log.info("{}", delayTask);
}
// 通过 taskId 查找延时任务,存在则执行给定逻辑
DelayTaskKit.ifPresent(newTaskId, delayTask -> {
delayTask.plusTimeMillis(500); // 增加 0.5 秒的延时时间
});
}
@Test
public void customTaskListener() {
// ---------------演示 - 增强 TaskListener ---------------
DelayTaskKit.of(new TaskListener() {
@Override
public void onUpdate() {
log.info("1.7 秒后执行的延时任务");
}
@Override
public boolean triggerUpdate() {
// 是否触发 onUpdate 监听回调方法
return TaskListener.super.triggerUpdate();
}
@Override
public Executor getExecutor() {
// 指定一个执行器来消费当前 onUpdate
Executors yourExecutors = ...;
return yourExecutors;
}
@Override
public void onException(Throwable e) {
// 异常回调
TaskListener.super.onException(e);
}
})
.plusTime(Duration.ofMillis(1700))
.task();
}
}
- 从以下版本开始:
- 21.16
- 作者:
- 渔民小镇
- 日期:
- 2024-09-01
-
类说明轻量可控的延时任务,任务到达指定时间后会执行、任务可取消、任务可增加延时时间轻量可控的延时任务工具类轻量可控延时任务域接口,负责轻量可控延时任务的创建、获取、取消、统计任务数量 ...等相关操作。