Spring 的 定時任務 @Scheduled

        實現定時任務,Java 提供的 ScheduledExecutorService 是較好的解決方案,它可以自行設置並行任務數量和每個任務的定時執行方式,具體本文不詳述。Spring 提供了更簡便的定時任務實現方式:註解 @Scheduled,它的底層就是對 ScheduledExecutorService 實現的封裝。

        首先,在啓動類或者某配置類上使用註解 @EnableScheduling 就開啓了定時任務,否則下文的註解不生效。

        其次,給某個方法加上 @Scheduled 註解即可將該方法設置爲定時執行的方法,但要注意定時方法返回值只能是void且不能有傳入參數。下面是 @Scheduled 支持的參數設置例子:

    /**
     * 每次方法執行完畢後,等待5s再執行此方法。
     *  同時只能有個線程運行此方法
     */
    @Scheduled(fixedDelay=5000)

    /**
     * 每隔5s調用一次此方法,無論之前的方法是否執行完畢
     *  同時可能有N個線程執行此方法
     */
    @Scheduled(fixedRate=5000)

    /***
     * initialDelay: 第一次調用此方法前的等待時間
     */ 
    @Scheduled(initialDelay=1000, fixedRate=5000)

    /**
     * 支持cron語法:
     * 每個參數的意義分別是: second, minute, hour, day of month, month, day of week
     *
     * 如下:週一至週五,每隔5s執行一次方法
     */
    @Scheduled(cron="*/5 * * * * SUN-MON")

        到這裏已經搞定了使用定時任務的基本工作了,但如果是到此爲止的話,項目中存在多個定時任務時,是都在同一個線程中執行的,同一時刻只能有一個任務在執行,這顯然並不是我們希望的。

        Spring 允許我們爲定時任務設置多線程(或單線程)的線程池,如下 demo 代碼所示:

@Configuration
@EnableScheduling // 啓動定時任務
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 配置定時任務線程池,一般是有多少個@Scheduled聲明的任務,corePoolSize就設置對應的數字
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(3));
    }
}

        其中 Executors.newScheduledThreadPool(3) 方法的傳參 corePoolSize 表示核心線程數,從一開始就創建好的,即使沒有任何任務需要執行,它們也會常駐後臺。

        通過這種方法創建的線程池並不意味着有多少個定時任務就必須設置多少個核心線程數,因爲執行中的定時任務數量超過了核心線程數後,線程池會繼續創建新的線程去執行更多任務,只是當線程空閒時最多保留 corePoolSize 個線程而已。如果有任務需要執行,已有的線程能夠立刻進行工作,否則需要創建,僅此而已。

        所以,當任務數量不是很多時,corePoolSize 設爲相對的數量是OK的,當任務數量較多時就不再建議設置一個超大的 corePoolSize,應該根據實際情況考慮如何設置。

        到這裏我們才終於算是大功告成了。

 

—— write by NOT IN【 無知無識 無言無聞 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章