七叶笔记 » java编程 » 一文搞懂如何实现Java,Spring动态启停定时任务

一文搞懂如何实现Java,Spring动态启停定时任务

为什么需要定时任务

定时任务的应用场景十分广泛,如定时清理文件、定时生成报表、定时数据同步备份等。

Java定时任务的原理

jdk自带的库中,有两种技术可以实现定时任务,一种是Timer,另一种是ScheduledThreadPoolExecutor

Timer+TimerTask

Timer是一个线程,控制执行TimerTask所需要执行的内容

其中,需要注意,Timer类有几个方法创建不同的线程执行:

延时执行

指定时间点执行

延时周期执行

指定时间点后周期执行

TimerTask是一个实现了Runable接口的类,所以能够放到线程去执行:

示例:

执行结果:

Tue May 30 13:45:47 CST 2022:  This is my job...Tue May 30 13:45:48 CST 2022:  This is my job...Tue May 30 13:45:49 CST 2022:  This is my job...Tue May 30 13:45:50 CST 2022:  This is my job...。。。。

弊端:Timer是单线程的,一旦定时任务中某一过程时刻抛出异常,将会导致整体线程停止,定时任务停止。

ScheduledThreadPoolExecutor

继承了ThreadPoolExecutor,,是一个基于线程池的调度器 通过实现ScheduledExecutorService接口方法去实现任务调度,主要方法如下:

延时执行

延时周期执行

每段延时间隔执行

示例:

执行结果:

Tue May 30 15:05:16 CST 2022: This is my job...Tue May 30 15:05:19 CST 2022: This is my job...Tue May 30 15:05:22 CST 2022: This is my job...Tue May 30 15:05:25 CST 2022: This is my job...。。。。。

Timer VS ScheduledThreadPoolExecutor

Timer

是单线程,如果开启多个线程服务,将会出现竞争,一旦出现异常,线程停止,定时任务停止;兼容性更高,jdk1.3后使用

ScheduledThreadPoolExecutor

基于线程池实现多线程,且自动调整线程数,线程出错并不会影响整体定时任务执行。在jdk1.5后可使用

Spring定时任务

Spring原生定时任务主要依靠@Scheduled注解实现:

Spring静态定时任务示例:

执行结果:

现在是:2022-05-30T16:03:40.006现在是:2022-05-30T16:04现在是:2022-05-30T16:04:40.003

@Scheduled定时任务原理(源码)

①项目启动扫描带有注解@Scheduled的所有方法信息由ScheduledAnnotationBeanPostProcessor的postProcessAfterInitialization方法实现功能:

②调用processScheduled方法将定时任务方法存放到任务队列中

③将任务解析并添加到任务队列后,交由ScheduledTaskRegistrar类的scheduleTasks方法添加(注册)定时任务到环境中:

由上述源码可以看出,Spring原生定时任务的大概步骤如下:

1.扫描带@Scheduled注解的类和方法(ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(........))

2.将定时任务解析完成后加入任务队列(ScheduledAnnotationBeanPostProcessor.processScheduled(........))

3.将定时任务注册到当前运行环境,等待执行(ScheduledTaskRegistrar.scheduleTasks(.......)) 且@Scheduled的底层调度实现是ScheduledThreadPoolExecutor

以上就是一文搞懂如何实现Java,Spring动态启停定时任务的详细内容,更多关于Java Spring启停定时任务的资料请关注七叶笔记其它相关文章!

相关文章