定时任务之SpringSchedule的注意事项

在咱们如今的项目中,或多或少的都会涉及到定时任务,Spring在3.0以后引入了SpringSchedule,这让咱们在使用Spring的时候,能够很容易的整合SpringSchedule.可是好用归好用,用的时候仍是有一些点注意的.java

SpringSchedule 中提供的定时任务,默认是单线程执行的,也就是说若是任务较多,或者某一个任务执行耗时比较久,那么显然易见,会很容易致使其他任务排队以及阻塞..net

既然存在这种问题,那么怎么去避免这种问题?这时候你们很容易想到的就是使用线程池,多个线程去跑定时任务.没错,正确的解决方案就是配置线程池.线程

之因此默认是单线程执行的,是由于当咱们没有配置taskSchedule的时候,默认建立的是一个单线程的线程池。具体代码解析参考:https://blog.csdn.net/weixin_40318210/article/details/78149692日志

先看一下没配置线程池的状况下的任务执行线程日志:orm

定时任务业务类的代码以下:blog

@Component
public class TaskConfig {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedDelayString = "5000") //单机
    public void getTask1() throws InterruptedException {
        //竞争锁逻辑代码 .....


        System.out.println("任务1,当前时间:" + dateFormat.format(new Date())+",线程号:"+Thread.currentThread().getName());
        //throw new RuntimeException("xxxxx");
        Thread.sleep(10000);
    }

    @Scheduled(cron = "0/5 * *  * * ?")
    public void getTask2() {
        System.out.println("任务2,当前时间:" + dateFormat.format(new Date())+",线程号:"+Thread.currentThread().getName());
    }

}

  

任务执行日志为:get

 

 

能够看到执行这两个任务的线程老是同一个线程.io

 

那么咱们如今加入线程池的配置,配置代码以下:form

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    //配置线程池---触发器和任务共用的
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

  

接下来咱们再观察一下定时任务的执行信息:class

 

 

如今看到是加入线程池后,每次执行的定时任务的线程在不断的变化,同时这两个任务也能够并行的执行,能够避免任务的阻塞与排队.

若是你的代码中使用了SpringSchedule,并且尚未使用线程池,那么赶忙去修改吧.

相关文章
相关标签/搜索