springboot自帶定時任務用法

定時任務的實現方式有很多種,本文是基於springboot註解方法的一種實現。

一、單線程定時任務

springboot實現定時任務主要是依靠兩個註解@Scheduled和@EnableScheduling,具體用法如下:

1)@Scheduled

在執行定時任務的方法上添加,代碼如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 *  springboot 註解單線程定時任務
 */
@Component
public class ScheduledSyncService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledSyncService.class);

    @Scheduled(fixedRate = 5000)
    public void executeScheduledTask1 () {
        LOGGER.info("this is {}", "executeScheduledTask1");
        LOGGER.info("the task execute time is {}", System.currentTimeMillis());
    }

    @Scheduled(cron = "0/2 * * * * ?")
    public void executeScheduledTask2 () {
        LOGGER.info("this is {}", "executeScheduledTask2");
        LOGGER.info("the task execute time is {}", System.currentTimeMillis());
    }

    @Scheduled(fixedDelay = 3000, initialDelay = 2000)
    public void executeScheduledTask3 () {
        LOGGER.info("this is {}", "executeScheduledTask3");
        LOGGER.info("the task execute time is {}", System.currentTimeMillis());
    }

}
2)@EnableScheduling

在項目啓動類上添加,代碼如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class MrtApplication {
   public static void main(String[] args) {
      SpringApplication.run(MrtApplication.class, args);
   }
}

單線程定時任務比較簡單,但多個定時任務由一個線程串行執行,一旦其中某個任務出現堵塞或不可預知問題,就會影響其它任務的執行。

二、多線程定時任務

多線程定時任務是在單線程定時任務的基礎開啓springboot異步調用功能,使用@EnableAsync、@Async和線程池實現的。

1)@EnableAsync

在項目啓動類上添加,代碼如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class MrtApplication {
   public static void main(String[] args) {
      SpringApplication.run(MrtApplication.class, args);
   }
}

此時即開啓了異步調用功能。

2)@Async

在定時任務類或執行方法上添加,如下:

@Scheduled(cron = "0/2 * * * * ?")
@Async
public void executeScheduledTask2 () {
    LOGGER.info("this is {}", "executor executeScheduledTask2");
    LOGGER.info("the task execute time is {}", System.currentTimeMillis());
}
3)線程池

可實現AsyncConfigurer接口,也可自定義實現,示例代碼是實現AsyncConfigurer接口。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig implements AsyncConfigurer {

    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncConfig.class);

    private int corePoolSize = 10;
    private int maxPoolSize = 90;
    private int queueCapacity = 15;

    @Bean
    @Override
    public Executor getAsyncExecutor () {
        LOGGER.info("this is {}", "getTaskExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        return executor;
    }
}

以上即實現多線程定時任務執行。

三、定時任務執行時間設置

在定時任務中使用@Scheduled註解參數來設置任務的執行時間,共有如下三種方式:
1、fixedRate:定義一個按一定頻率執行的定時任務
2、fixedDelay:定義一個按一定頻率執行的定時任務,與上面不同的是,該屬性可以配合initialDelay屬性, 定義該任務延遲執行時間。
3、cron:通過表達式來配置任務執行時間
下面重點介紹一下cron表達式設置方式,如下:
cron表達式是一個字符串,以5或6個空格隔開,分開共6或7個域,每一個域代表一個含義。
語法如下:

[秒] [分] [小時] [日] [月] [周] [年]

其中“年”不是必須域,可以省略。每個域的用法如下:
在這裏插入圖片描述
通配符用法說明:

  • *表示所有值。 例如:在分的字段上設置 *,表示每一分鐘都會觸發。
  • 表示不指定值。使用的場景爲不需要關心當前設置這個字段的值,僅被用於天(月)和天(星期)兩個子表達式,當2個子表達式其中之一被指定了值以後,爲了避免衝突,需要將另一個子表達式的值設爲“?”。例如:要在每月的10號觸發一個操作,但不關心是周幾,所以需要周位置的那個字段設置爲”?” ,即設置爲 0 0 0 10 * ?
  • - 表示區間。例如 :在小時上設置 “10-12”,表示 10、11、12點都會觸發。
  • 表示指定多個值,例如在周字段上設置 “MON,WED,FRI” 表示週一、週三和週五觸發。
  • / 用於遞增觸發。例如:在秒上面設置“5/15” 表示從5秒開始,每增15秒觸發(5、20、35、50)。 在月字段上設置“1/3”所示每月1號開始,每隔三天觸發一次。
  • L 表示最後的意思。在日字段設置上,表示當月的最後一天(依據當前月份,如果是二月還會依據是否是潤年[leap]),在周字段上表示星期六,相當於”7”或”SAT”。如果在”L”前加上數字,則表示該數據的最後一個。例如在周字段上設置“6L”這樣的格式,則表示“本月最後一個星期五”。
  • W 表示離指定日期的最近那個工作日(週一至週五)。例如在日字段上置“5W”,表示離每月15號最近的那個工作日觸發。如果15號正好是週六,則找最近的週五(14號)觸發, 如果15號是周未,則找最近的下週一(16號)觸發;如果15號正好在工作日(週一至週五),則就在該天觸發。如果指定格式爲 “1W”,它則表示每月1號往後最近的工作日觸發。如果1號正是週六,則將在3號下週一觸發。(注,”W”前只能設置具體的數字,不允許區間”-“)。
  • # 序號(表示每月的第幾個周幾),例如在周字段上設置“6#3”表示在每月的第三個週六。注意如果指定”#5”,正好第五週沒有周六,則不會觸發該配置(用在母親節和父親節再合適不過了) ;
  • 小提示:LW可以一組合使用。如果在日字段上設置“LW”,則表示在本月的最後一個工作日觸發;周字段的設置,若使用英文字母是不區分大小寫的,即MON與mon相同。

在線生成表達式:http://qqe2.com/cron/index

舉例如下:

  • /5 * * * ? 每隔5秒執行一次
  • 0 /1 * * ? 每隔1分鐘執行一次
  • 0 0 10,14,16 * * ? 每天上午10點,下午2點,4點
  • 0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時
  • 0 0 12 ? * WED 表示每個星期三中午12點
  • 0 0 12 * * ? 每天中午12點觸發
  • 0 15 10 ? * * 每天上午10:15觸發
  • 0 15 10 * * ? 每天上午10:15觸發
  • 0 15 10 * * ? * 每天上午10:15觸發
  • 0 15 10 * * ? 2005 2005年的每天上午10:15觸發
  • 0 * 14 * * ? 在每天下午2點到下午2:59期間的每1分鐘觸發
  • 0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸發
  • 0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發
  • 0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸發
  • 0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44觸發
  • 0 15 10 ? * MON-FRI 週一至週五的上午10:15觸發
  • 0 15 10 15 * ? 每月15日上午10:15觸發
  • 0 15 10 L * ? 每月最後一日的上午10:15觸發
  • 0 15 10 ? * 6L 每月的最後一個星期五上午10:15觸發
  • 0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最後一個星期五上午10:15觸發
  • 0 15 10 ? * 6#3 每月的第三個星期五上午10:15觸發
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章