程序包 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
  • 说明
    轻量可控的延时任务,任务到达指定时间后会执行、任务可取消、任务可增加延时时间
    轻量可控的延时任务工具类
    轻量可控延时任务域接口,负责轻量可控延时任务的创建、获取、取消、统计任务数量 ...等相关操作。