spring boot中使用@Async實(shí)現(xiàn)異步調(diào)用任務(wù)
什么是“異步調(diào)用”?
“異步調(diào)用”對(duì)應(yīng)的是“同步調(diào)用”,同步調(diào)用指程序按照定義順序依次執(zhí)行,每一行程序都必須等待上一行程序執(zhí)行完成之后才能執(zhí)行;異步調(diào)用指程序在順序執(zhí)行時(shí),不等待異步調(diào)用的語(yǔ)句返回結(jié)果就執(zhí)行后面的程序。
同步調(diào)用
下面通過(guò)一個(gè)簡(jiǎn)單示例來(lái)直觀的理解什么是同步調(diào)用:
定義Task類(lèi),創(chuàng)建三個(gè)處理函數(shù)分別模擬三個(gè)執(zhí)行任務(wù)的操作,操作消耗時(shí)間隨機(jī)取(10秒內(nèi))
package com.kfit.task;
import java.util.Random;
import org.springframework.stereotype.Component;
/**
* 定義3個(gè)任務(wù)
* @author Angel(QQ:412887952)
* @version v.0.1
*/
@Component
publicclass Task1 {
//定義一個(gè)隨機(jī)對(duì)象.
publicstatic Random random =new Random();
//任務(wù)一;
publicvoid doTaskOne() throws Exception {
System.out.println("開(kāi)始做任務(wù)一");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)一,耗時(shí):" + (end - start) + "毫秒");
}
//任務(wù)二;
publicvoid doTaskTwo() throws Exception {
System.out.println("開(kāi)始做任務(wù)二");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)二,耗時(shí):" + (end - start) + "毫秒");
}
//任務(wù)3;
publicvoid doTaskThree() throws Exception {
System.out.println("開(kāi)始做任務(wù)三");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)三,耗時(shí):" + (end - start) + "毫秒");
}
}
編寫(xiě)一個(gè)訪問(wèn)方法:
//測(cè)試task1.
@RequestMapping("/task1")
public String task1() throws Exception{
task1.doTaskOne();
task1.doTaskTwo();
task1.doTaskThree();
return"task1";
}
運(yùn)行可以看到類(lèi)似如下輸出:
開(kāi)始做任務(wù)一
完成任務(wù)一,耗時(shí):4156毫秒
開(kāi)始做任務(wù)二
完成任務(wù)二,耗時(shí):557毫秒
開(kāi)始做任務(wù)三
完成任務(wù)三,耗時(shí):6171毫秒
異步調(diào)用
上述的同步調(diào)用雖然順利的執(zhí)行完了三個(gè)任務(wù),但是可以看到執(zhí)行時(shí)間比較長(zhǎng),若這三個(gè)任務(wù)本身之間不存在依賴(lài)關(guān)系,可以并發(fā)執(zhí)行的話,同步調(diào)用在執(zhí)行效率方面就比較差,可以考慮通過(guò)異步調(diào)用的方式來(lái)并發(fā)執(zhí)行。
在Spring Boot中,我們只需要通過(guò)使用@Async注解就能簡(jiǎn)單的將原來(lái)的同步函數(shù)變?yōu)楫惒胶瘮?shù),Task類(lèi)改在為如下模式:
package com.kfit.task;
import java.util.Random;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 定義3個(gè)任務(wù)
* @author Angel(QQ:412887952)
* @version v.0.1
*/
@Component
publicclass Task2 {
//定義一個(gè)隨機(jī)對(duì)象.
publicstatic Random random =new Random();
//任務(wù)一;
@Async
publicvoid doTaskOne() throws Exception {
System.out.println("開(kāi)始做任務(wù)一");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)一,耗時(shí):" + (end - start) + "毫秒");
}
//任務(wù)二;
@Async
publicvoid doTaskTwo() throws Exception {
System.out.println("開(kāi)始做任務(wù)二");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)二,耗時(shí):" + (end - start) + "毫秒");
}
//任務(wù)3;
@Async
publicvoid doTaskThree() throws Exception {
System.out.println("開(kāi)始做任務(wù)三");
longstart = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
longend = System.currentTimeMillis();
System.out.println("完成任務(wù)三,耗時(shí):" + (end - start) + "毫秒");
}
}
為了讓@Async注解能夠生效,還需要在Spring Boot的主程序中配置@EnableAsync,如下所示:
@SpringBootApplication
@EnableAsync
publicclass App {
//省略其它代碼…
}
編寫(xiě)測(cè)試方法:
//測(cè)試task2.
@RequestMapping("/task2")
public String task2() throws Exception{
task2.doTaskOne();
task2.doTaskTwo();
task2.doTaskThree();
return"task2";
}
此時(shí)可以反復(fù)執(zhí)行單元測(cè)試,您可能會(huì)遇到各種不同的結(jié)果,比如:
開(kāi)始做任務(wù)一
開(kāi)始做任務(wù)二
開(kāi)始做任務(wù)三
完成任務(wù)三,耗時(shí):57毫秒
完成任務(wù)二,耗時(shí):3621毫秒
完成任務(wù)一,耗時(shí):7419毫秒
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- spring boot使用自定義配置的線程池執(zhí)行Async異步任務(wù)
- spring boot異步(Async)任務(wù)調(diào)度實(shí)現(xiàn)方法
- SpringBoot實(shí)現(xiàn)定時(shí)任務(wù)和異步調(diào)用
- SpringBoot用@Async注解實(shí)現(xiàn)異步任務(wù)
- Springboot任務(wù)之異步任務(wù)的使用詳解
- 詳細(xì)講解springboot如何實(shí)現(xiàn)異步任務(wù)
- SpringBoot詳細(xì)講解異步任務(wù)如何獲取HttpServletRequest
- Spring?Boot小型項(xiàng)目如何使用異步任務(wù)管理器實(shí)現(xiàn)不同業(yè)務(wù)間的解耦
相關(guān)文章
Mybatis-Plus進(jìn)階分頁(yè)與樂(lè)觀鎖插件及通用枚舉和多數(shù)據(jù)源詳解
這篇文章主要介紹了Mybatis-Plus的分頁(yè)插件與樂(lè)觀鎖插件還有通用枚舉和多數(shù)據(jù)源的相關(guān)介紹,文中代碼附有詳細(xì)的注釋?zhuān)信d趣的朋友來(lái)看看吧2022-03-03
Nacos的單機(jī)模式啟動(dòng)失敗問(wèn)題及解決
這篇文章主要介紹了Nacos的單機(jī)模式啟動(dòng)失敗問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
SpringCloud?Gateway讀取Request?Body方式
這篇文章主要介紹了SpringCloud?Gateway讀取Request?Body方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot+Email發(fā)送郵件的實(shí)現(xiàn)示例
Spring?Boot提供了簡(jiǎn)單而強(qiáng)大的郵件發(fā)送功能,本文主要介紹了SpringBoot+Email發(fā)送郵件的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
Java數(shù)組的遍歷與求和知識(shí)點(diǎn)
本篇文章給大家總計(jì)了Java數(shù)組的遍歷與求和的知識(shí)點(diǎn)以及需要注意的地方,需要的朋友參考學(xué)習(xí)下。2018-02-02

