定時任務實現的幾種方式:
- Timer:這是java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務。使用這種方式可以讓你的程序按照某一個頻度執行,但不能在指定時間運行。一般用的較少。
- ScheduledExecutorService:也jdk自帶的一個類;是基於線程池設計的定時任務類,每個調度任務都會分配到線程池中的一個線程去執行,也就是說,任務是並發執行,互不影響。
- Spring Task:Spring3.0以后自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
- Quartz:這是一個功能比較強大的的調度器,可以讓你的程序在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯復雜。
下面說的是 spring自帶的定時任務。
SpringBoot使用注解方式開啟定時任務添加注解方式
開發中定時任務,要和別的業務類分開寫。這樣處理起來方便。
1)啟動類里面 @EnableScheduling開啟定時任務,自動掃描
2)定時任務業務類 加注解 @Component被容器掃描
3)定時執行的方法加上注解 @Scheduled(fixedRate=2000) 定期執行一次
@SpringBootApplication //一個注解頂下面3個
@EnableScheduling //開啟定時任務
@EnableAsync //開啟異步任務
public class XdclassApplication {
public static void main(String[] args) {
SpringApplication.run(XdclassApplication.class, args);
}
}
//定時任務類
@Component
public class AsyncTask {
@Scheduled(fixedRate=2000)
public void task1() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任務1耗時="+(end-begin));
}
public void task2() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任務2耗時="+(end-begin));
}
//定時任務需要返回值的情況
public Future<String> task4() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任務4耗時="+(end-begin));
return new AsyncResult<String>("任務4");
}
public Future<String> task5() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
System.out.println("任務5耗時="+(end-begin));
return new AsyncResult<String>("任務5");
}
SpringBoot2.x異步任務實戰(核心知識) 不一定是要和上面的定時任務一起使用還有很多場景的。需要異步處理的任務,最好單獨的封裝在一個類中。這樣好處理。
簡介:講解什么是異步任務,和使用SpringBoot2.x開發異步任務實戰
1、什么是異步任務和使用場景:適用於處理log、發送郵件、短信……等
下單接口->查庫存 100
余額校驗 150
風控用戶100
2、啟動類里面使用@EnableAsync注解開啟功能,自動掃描
3、定義異步任務類並使用@Component標記組件被容器掃描,異步方法加上@Async
注意點:
1)要把異步任務封裝到類里面,不能直接寫到Controller
2)增加Future<String> 返回結果 AsyncResult<String>("task執行完成");
3)如果需要拿到結果 需要判斷全部的 task.isDone()
4、通過注入方式,注入到controller里面,如果測試前后區別則改為同步則把Async注釋掉
@Component
@Async
public class AsyncTask {
@Scheduled(fixedRate=2000)
public void task1() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任務1耗時="+(end-begin));
}
public void task2() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任務2耗時="+(end-begin));
}
//定時任務需要返回值的情況
public Future<String> task4() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任務4耗時="+(end-begin));
return new AsyncResult<String>("任務4");
}
public Future<String> task5() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
System.out.println("任務5耗時="+(end-begin));
return new AsyncResult<String>("任務5");
}
}
@GetMapping("async_task")
public JsonData exeTask() throws InterruptedException{
long begin = System.currentTimeMillis();
Future<String> task4 = task.task4();
Future<String> task5 = task.task5();
for(;;){
if (task4.isDone() && task5.isDone() ) {
break;
}
}
long end = System.currentTimeMillis();
long total = end-begin;
System.out.println("執行總耗時="+total);
return JsonData.buildSuccess(total);
}
