1. 程式人生 > >SpringBoot中使用Scheduling執行定時任務

SpringBoot中使用Scheduling執行定時任務

SpringBoot自帶的 Schedule,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多

以下任務都是在單執行緒下執行的

第一步 建立SpringBoot專案

第二步 新增@EnableScheduling開啟定時任務

第三步 設定定時需要執行的任務

有兩種方法設定執行時機

第一種我們就且叫他為普通方法

1.fixedRate:會為所有任務的開始執行時間編排一個表,假如fixedRate=5000,且第一次開始時間是10:00:00

任務 開始執行時間
任務1 10:00:00
任務2 10:00:05
任務3 10:00:10
任務4 10:00:15
任務5 10:00:20

   當執行任務耗時小於fixedRate設定的時間時,將會按照表中的開始時間執行任務,即每隔5秒會執行一個任務:

@Component
public class TestScheduling {
    private static final Logger LOG = LoggerFactory.getLogger(TestScheduling.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(fixedRate=5000)
    public void myTask() throws InterruptedException {
        LOG.info("執行時間:{}",sdf.format(new Date()));
    }
}

      

   當執行任務耗時大於fixedRate設定的時間時,以下一張圖就很清楚的表示了(圖的出處

解析一下:

fixedRate設定的也是為fixedRate=5000

第一個任務開始執行時間是0:00,耗時8秒

第二個任務本應該開始執行時間是0:05,但是第一個任務執行完時間已經是0:08,所以第二個任務在第一個任務執行完畢之後會立即執行,耗時是3s

第三個任務本應該開始執行時間是0:10,但是前兩個任務執行完畢時間已經是0:11,所以第三個任務在第二個任務執行完畢之後會立即執行,耗時是3s

第四個任務,也同第二、第三個任務一樣,在預計開始執行的時間(這裡第四個任務預計開始執行時間是0:15),因為上一個任務還沒有執行完畢,所以要等待上一個人執行完畢之後才會執行。

第五個任務預計開始執行時間是0:20,而前四個任務在0:19已經執行完畢,需要等待1秒,到達我們預計的開始執行時間(0:20)才會執行第五個任務。

2.fixedDelay

這個就比之前的fixedRate簡單得多。如設定fixedRate=5000.下一個任務只需要盯著上一個任務的屁股(執行完畢的時間)就行了。上一個任務執行完畢5秒之後,下一個任務就會開始執行

@Component
public class TestScheduling {
    private static final Logger LOG = LoggerFactory.getLogger(TestScheduling.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(fixedDelay=5000)
    public void myTask(){
        LOG.info("開始執行時間:{}",sdf.format(new Date()));
        try {
            Thread.sleep(8000);//讓任務執行的耗時時間為8秒,有利於我們的觀察
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOG.info("執行完畢時間:{}",sdf.format(new Date()));
    }
}

3.initialDelay

用於配合fixedRate和fixedDelay使用的,作用是在容器啟動後經過多長時間才開始執行第一次任務。

4.擴充套件一下

我們先看下一下@Scheduled註解裡面有什麼

 fixedDelayString、fixedRateString和initialDelayString不就是我們上面講的三個加個字串嘛,之前的三個都是long型別,這三個是String型別,顧名思義,不就是用字串表示嘛。作用其實就是為了能在application.properties配置

@Component
public class TestScheduling {
    private static final Logger LOG = LoggerFactory.getLogger(TestScheduling.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(initialDelay = 5000,fixedDelayString = "${com.liang.scheduled:5000}")
    public void myTask(){
        LOG.info("開始執行時間:{}",sdf.format(new Date()));
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOG.info("執行完畢時間:{}",sdf.format(new Date()));
    }
}

 :5000作用是防止application.properties沒有配置com.liang.scheduled屬性則使用預設的5000(如果沒有寫:5000且application.properties沒有配置com.liang.scheduled屬性會報異常)

執行結果:和我們預計的一樣,下一次開始執行時間與上一次結束時間間隔正好是10秒。如果去掉application.properties中的com.liang.scheduled屬性,則間隔時間是預設的5秒,這個自行驗證。

第二種cron表示式

網站:http://cron.qqe2.com/

這個自行去網站上設定,然後複製表示式過來就行,