大家都知道@Scheduled注解可以很方便的帮助我们执行定时任务
只需要在启动类上加上@EnableScheduling注解,然后在相应的需要执行任务的方法上加上@Scheduled注解,并且配置上需要的cron表达式就可以了
但是一直对@Scheduled 有两个问题(通过以下测试,解决了我的问题,在这里做个记录)
1. 如果我的任务是每5秒执行一次,但是该任务的执行时间有可能大于5秒,比如我需要6秒才能把这个任务执行完,那么该定时任务该如何执行?在没有执行完的时候,下一次定时的时间到了之后,还会进入该任务吗?
接下来就做个测试,附上代码
运行结果如下:
事实证明,如果我们的任务执行时间大于cron指定的时间的话,那么,定时任务会在当前任务执行完之后才会执行下一次的定时
也就是说正常的话,我们的执行时间应该是
15:00:20->15:00:25->15:00:30->15:00:35->15:00:40->15:00:45......这样一次类推
但是我们需要的执行时间大于5秒,也就是说,
15:00:25要来执行该定时的时候,发现上一次的任务还没有执行完,所以就放弃本次的执行
15:00:30的时候又来了,发现,上一次的任务已经执行完了,所以就开始执行
15:00:35要来执行该定时的时候,发现上一次的任务还没有执行完,所以就放弃本次的执行
15:00:40的时候又来了,发现,上一次的任务已经执行完了,所以就开始执行
这样以此类推,于是,就会出现上面的情况.... 好了,第一个问题解决了!
-----------------------------------------------------------------------------------------------------------------------
2.如果一个程序中有两个定时任务,那么spring 是如何帮我们执行的呢?
场景如下:
我的程序中有两个任务需要执行,都是每5秒执行一次,代码如下:
很简单就是两个普通的任务,那么我现在启动程序, 结果会让人吃惊,因为正常我们觉得这两个任务应该是并行执行的,你执行你的,我执行我的,互不影响.但是结果却是.....
很明细,这两个任务好像是用的一个线程,在排着队的执行,这样肯定是不合适的,也不符合我们的要求的.后来发现,只需要加上个配置即可:
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}
再次执行:
这回正常了
-----------------------------------------------------------------------------------------------