文章目錄
一. 定時任務簡介
- 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捨棄不用
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);
}
}
-
總消耗時間,毫秒級
-
其中在這裏我使用的小工具:JsonData.java,當然是主要用於返回值的比較美觀。
-
JsonData.java 大家可以參考我的另一篇博客詳細代碼在裏面最後有介紹:https://blog.csdn.net/weixin_43330884/article/details/105046825