美文网首页
如何动态控制定时器的调度呢?

如何动态控制定时器的调度呢?

作者: guessguess | 来源:发表于2021-08-24 09:29 被阅读0次

由于工作上需求的需要,需要动态控制定时任务的执行时机,这块一开始在使用的时候不太不清楚实现原理。
后面专门去看了一下源码。

class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {

    @Override
    public void run() {
        Date actualExecutionTime = new Date();
        1.super.run其实就是我们自定义的要执行的方法
        super.run();
        Date completionTime = new Date();
        synchronized (this.triggerContextMonitor) {
            Assert.state(this.scheduledExecutionTime != null, "No scheduled execution");
            this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
            2.查看任务是否已经被取消
            if (!obtainCurrentFuture().isCancelled()) {
               3.执行完了进行下一次调度
                schedule();
            }
        }
    }

    @Nullable
    public ScheduledFuture<?> schedule() {
        synchronized (this.triggerContextMonitor) {
            4.通过触发器获取下次执行时间
            this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
            if (this.scheduledExecutionTime == null) {
                return null;
            }
            5.由于是通过延时调用,通过下次执行时间就可以得知延时多久执行,再次执行
            long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
            this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
            return this;
        }
    }

}

从整个过程来看,其实分为好几步。
1.执行定时器任务的run方法(可以理解为业务方法)
2.判断任务是否被取消
3.完成之后进行下一次调度
4.通过触发器获取下次执行时间
5.计算出延时执行时间
6.执行
。。。循环回到1,2,3

那么如何实现动态调度?

从源码得知,第4点,每次执行都是通过触发器获取下次执行时间,所以我们只需要将cron表达式持久化,让触发器每次都从数据库里面去读最新的cron表达式,根据新的cron表达式就可以计算出下次的执行时间。
这样子就可以做到动态调度了。
如何动态修改定时任务的调度呢

最后如果要支持定时任务的新增 删除以及分布式的话,可以考虑使用quartz。这个组件支持更多的功能

相关文章

网友评论

      本文标题:如何动态控制定时器的调度呢?

      本文链接:https://www.haomeiwen.com/subject/ofvlbltx.html