在开发的时候,我们可能会经常使用SpringBoot中的@Scheduled来实现定时任务,但是在使用过程中可能常常会遇到一些些问题
本来一个定时任务是3秒执行一次,可是过了3秒还是没有执行。这个时候我们就知道为什么会出现这个问题?
其实,SpringBoot中的@Scheduled默认是单线程在执行的,这就会出现阻塞。一定要等到一个任务执行完成,才会继续执行下一个任务。所以就出现上述情况。
如何证明啦?下面上代码:
@Component
public class TimeTaskJob {
@Scheduled(cron = "0/10 * * * * ?")
public void SpringTimeTask() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("调度任务一:" + DateUtils.formatDateByFormat(new Date(), DateUtils.PATTERN_4));
System.out.println(
"Springboot调度任务一: " + Thread.currentThread().getId() + "----" + Thread.currentThread().getName());
}
@Scheduled(cron = "0/10 * * * * ?")
public void SpringTimeTask2() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("调度任务二:" + DateUtils.formatDateByFormat(new Date(), DateUtils.PATTERN_4));
System.out.println(
"Springboot调度任务二: " + Thread.currentThread().getId() + "----" + Thread.currentThread().getName());
}
}
上面代码定义了两个定时任务,打印了对应的执行线程的Id和名字,我们看是否是同一线程执行就可以确认是否同一线程。
上图结论:
1、多个定时任务同一线程执行
2、执行完第一个线程,才开始执行第二个线程。
那有没有办法让两个线程同时开始执行,且互不影响啦?这肯定是有的啦,必须要相信SpringBoot的强大。
我们只要实现SchedulingConfigurer类,并重写他的方法就OK
@EnableScheduling
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}
}
执行结果:
我们可以看到执行结果,两个调度任务是同时执行的,且分别由不同的线程执行。至此顺利解决了@Scheduled的坑