spring boot的定時任務,基於Cron表達式

一. 定時任務簡介

  • JDK自帶定時任務Timer類 簡單易用,但由於所有任務都是由同一個線程來調度,因此所有任務都是串行執行的,同一時間只能有一個任務在執行,前一個任務的延遲或異常都將會影響到之後的任務 在Java5推出了:ScheduledExecutor 用線程池操作,更好地支持了併發操作
  • Quartz框架 配置簡單靈活,可以使用xml或者註解方式
  • Schedule也是Springboot常用的定時任務 配置簡單,易用

1. schedule基本使用步驟

  • 啓動類裏面 @EnableScheduling開啓定時任務,自動掃描
  • 定時任務業務類 加註解 @Component被容器掃描
  • 定時執行的方法加上註解 @Scheduled(fixedRate=2000) 定期執行一次

2. 其他配置

  • cron配置定時任務表達式官方文檔 https://tool.lu/crontab/
  • fixedRate: 定時多久執行一次(上一次開始執行時間點後xx秒再次執行;)
  • fixedDelay: 上一次執行結束時間點後xx秒再次執行
  • fixedDelayString: 字符串形式,可以通過配置文件指定

二. 代碼編寫

1. 同步定時任務

1.1 在啓動類上面添加註解
@EnableScheduling	//掃描定時任務
1.2 定時任務類
  • 創建一個類用於測試:
package cn.hp.springboot_day05.task;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 定時任務類
 * 單獨寫法
 */
@Component  //交給spring管理
public class TaskTest {

    //@Scheduled(fixedRate = 3000)
    public void test(){
        System.out.println("定時任務執行......"+ new Date());
    }

	//每三秒執行一次
    @Scheduled(cron = "*/3 * * * * *")
    public void test1(){
        System.out.println("定時任務執行......"+ new Date());
    }

}

  • 效果圖:
    在這裏插入圖片描述
  • Cron語法格式
    比如: @Scheduled(cron = “*/3 * * * * *”) 代表每隔3秒執行一次
    六個 * 號代表如圖:
    因爲定時任務很少或沒有以年爲單位的所以最後一個year捨棄不用
    ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200325142506841.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMzMDg4NA==,size_16,color_FFFFFF,t_7

2. 異步定時任務

異步任務的作用:減少程序運行時間、提升系統響應速度、快速響應用戶!

2.1 使用註解開啓

在啓動類上面添加註解:@EnableAsync //開啓異步定時任務

@SpringBootApplication
@EnableAsync    //開啓異步定時任務
public class SpringbootDay05Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootDay05Application.class, args);
    }
}
2.2 創建異步任務類

每個方法加上註解@Async,如果加到類上,表明所有方法都異步執行

package cn.hp.springboot_day05.task;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;

/**
 * 異步定時任務
 */
@Component
public class AsyncTaskTest {

	//註解@Async表明此方法是異步執行的
    @Async
    public Future<String> async() throws InterruptedException {
        long begin = System.currentTimeMillis();

        Thread.sleep(2000);//此處設置了休眠兩秒

        long end = System.currentTimeMillis();
        long time = end-begin;
        System.out.println("異步任務一執行時間:"+time);

        return new AsyncResult<String>("異步任務一執行完畢");
    }

    @Async
    public Future<String> async1() throws InterruptedException {
        long begin = System.currentTimeMillis();

        Thread.sleep(2000);

        long end = System.currentTimeMillis();
        long time = end-begin;
        System.out.println("異步任務二執行時間:"+time);

        return new AsyncResult<String>("異步任務二執行完畢");
    }

    @Async
    public Future<String> async2() throws InterruptedException {
        long begin = System.currentTimeMillis();

        Thread.sleep(2000);

        long end = System.currentTimeMillis();
        long time = end-begin;
        System.out.println("異步任務三執行時間:"+time);

        return new AsyncResult<String>("異步任務三執行完畢");
    }
}

2.3 測試異步任務執行時間
  • 創建測試類
package cn.hp.springboot_day05.controller;

import cn.hp.springboot_day05.task.AsyncTaskTest;
import cn.hp.springboot_day05.utils.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;

@RestController
@RequestMapping("/async")
public class AsyncController {

    @Autowired
    private AsyncTaskTest taskTest;

    @RequestMapping("/test")
    public JsonData asyncTest() throws InterruptedException {

        long begin = System.currentTimeMillis();
        Future<String> async = taskTest.async();
        Future<String> async1 = taskTest.async1();
        Future<String> async2 = taskTest.async2();

        Thread.sleep(2000);//模擬網絡請求,休眠2秒

        while (true){
            if (async.isDone()&&async1.isDone()&&async2.isDone()){
                break;//異步任務所有都執行結束則中斷循環
            }
        }
        long end = System.currentTimeMillis();
        long time = end-begin;
        System.out.println("總執行時間:"+time);
        return JsonData.buildSuccess(time);
    }
}

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