spring boot中使用@Async實現(xiàn)異步調(diào)用任務
什么是“異步調(diào)用”?
“異步調(diào)用”對應的是“同步調(diào)用”,同步調(diào)用指程序按照定義順序依次執(zhí)行,每一行程序都必須等待上一行程序執(zhí)行完成之后才能執(zhí)行;異步調(diào)用指程序在順序執(zhí)行時,不等待異步調(diào)用的語句返回結(jié)果就執(zhí)行后面的程序。
同步調(diào)用
下面通過一個簡單示例來直觀的理解什么是同步調(diào)用:
定義Task類,創(chuàng)建三個處理函數(shù)分別模擬三個執(zhí)行任務的操作,操作消耗時間隨機取(10秒內(nèi))
package com.kfit.task; import java.util.Random; import org.springframework.stereotype.Component; /** * 定義3個任務 * @author Angel(QQ:412887952) * @version v.0.1 */ @Component publicclass Task1 { //定義一個隨機對象. publicstatic Random random =new Random(); //任務一; publicvoid doTaskOne() throws Exception { System.out.println("開始做任務一"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務一,耗時:" + (end - start) + "毫秒"); } //任務二; publicvoid doTaskTwo() throws Exception { System.out.println("開始做任務二"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務二,耗時:" + (end - start) + "毫秒"); } //任務3; publicvoid doTaskThree() throws Exception { System.out.println("開始做任務三"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務三,耗時:" + (end - start) + "毫秒"); } }
編寫一個訪問方法:
//測試task1. @RequestMapping("/task1") public String task1() throws Exception{ task1.doTaskOne(); task1.doTaskTwo(); task1.doTaskThree(); return"task1"; }
運行可以看到類似如下輸出:
開始做任務一
完成任務一,耗時:4156毫秒
開始做任務二
完成任務二,耗時:557毫秒
開始做任務三
完成任務三,耗時:6171毫秒
異步調(diào)用
上述的同步調(diào)用雖然順利的執(zhí)行完了三個任務,但是可以看到執(zhí)行時間比較長,若這三個任務本身之間不存在依賴關(guān)系,可以并發(fā)執(zhí)行的話,同步調(diào)用在執(zhí)行效率方面就比較差,可以考慮通過異步調(diào)用的方式來并發(fā)執(zhí)行。
在Spring Boot中,我們只需要通過使用@Async注解就能簡單的將原來的同步函數(shù)變?yōu)楫惒胶瘮?shù),Task類改在為如下模式:
package com.kfit.task; import java.util.Random; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; /** * 定義3個任務 * @author Angel(QQ:412887952) * @version v.0.1 */ @Component publicclass Task2 { //定義一個隨機對象. publicstatic Random random =new Random(); //任務一; @Async publicvoid doTaskOne() throws Exception { System.out.println("開始做任務一"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務一,耗時:" + (end - start) + "毫秒"); } //任務二; @Async publicvoid doTaskTwo() throws Exception { System.out.println("開始做任務二"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務二,耗時:" + (end - start) + "毫秒"); } //任務3; @Async publicvoid doTaskThree() throws Exception { System.out.println("開始做任務三"); longstart = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); longend = System.currentTimeMillis(); System.out.println("完成任務三,耗時:" + (end - start) + "毫秒"); } }
為了讓@Async注解能夠生效,還需要在Spring Boot的主程序中配置@EnableAsync,如下所示:
@SpringBootApplication @EnableAsync publicclass App { //省略其它代碼… }
編寫測試方法:
//測試task2. @RequestMapping("/task2") public String task2() throws Exception{ task2.doTaskOne(); task2.doTaskTwo(); task2.doTaskThree(); return"task2"; }
此時可以反復執(zhí)行單元測試,您可能會遇到各種不同的結(jié)果,比如:
開始做任務一
開始做任務二
開始做任務三
完成任務三,耗時:57毫秒
完成任務二,耗時:3621毫秒
完成任務一,耗時:7419毫秒
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaWeb?Servlet實現(xiàn)文件上傳與下載功能實例
因自己負責的項目中需要實現(xiàn)文件上傳,所以下面下面這篇文章主要給大家介紹了關(guān)于JavaWeb?Servlet實現(xiàn)文件上傳與下載功能的相關(guān)資料,需要的朋友可以參考下2022-04-04解決SpringCloud Feign傳對象參數(shù)調(diào)用失敗的問題
這篇文章主要介紹了解決SpringCloud Feign傳對象參數(shù)調(diào)用失敗的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06解決SpringBoot運行Test時報錯:SpringBoot Unable to find
這篇文章主要介紹了SpringBoot運行Test時報錯:SpringBoot Unable to find a @SpringBootConfiguration,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決
這篇文章主要介紹了springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09