定時任務之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,並且尚未使用線程池,那麼趕忙去修改吧.

相關文章
相關標籤/搜索