定時任務之SpringSchedule的注意事項


在我們現在的項目中,或多或少的都會涉及到定時任務,Spring在3.0之后引入了SpringSchedule,這讓我們在使用Spring的時候,可以很容易的整合SpringSchedule.但是好用歸好用,用的時候還是有一些點注意的.

SpringSchedule 中提供的定時任務,默認是單線程執行的,也就是說如果任務較多,或者某一個任務執行耗時比較久,那么顯然易見,會很容易導致其余任務排隊以及阻塞.

既然存在這種問題,那么怎么去避免這種問題?這時候大家很容易想到的就是使用線程池,多個線程去跑定時任務.沒錯,正確的解決方案就是配置線程池.

之所以默認是單線程執行的,是因為當我們沒有配置taskSchedule的時候,默認創建的是一個單線程的線程池。具體代碼解析參考:https://blog.csdn.net/weixin_40318210/article/details/78149692

先看一下沒配置線程池的情況下的任務執行線程日志:

定時任務業務類的代碼如下:

@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());
    }

}

  

任務執行日志為:

 

 

可以看到執行這兩個任務的線程總是同一個線程.

 

那么我們現在加入線程池的配置,配置代碼如下:

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

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

    //配置線程池---觸發器和任務共用的
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

  

接下來我們再觀察一下定時任務的執行信息:

 

 

現在看到是加入線程池后,每次執行的定時任務的線程在不斷的變化,同時這兩個任務也可以並行的執行,可以避免任務的阻塞與排隊.

如果你的代碼中使用了SpringSchedule,而且還沒有使用線程池,那么趕緊去修改吧.

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM