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類,創(chuàng)建三個(gè)處理函數(shù)分別模擬三個(gè)執(zhí)行任務(wù)的操作,操作消耗時(shí)間隨機(jī)?。?0秒內(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) + "毫秒"); } }
編寫一個(gè)訪問(wèn)方法:
//測(cè)試task1. @RequestMapping("/task1") public String task1() throws Exception{ task1.doTaskOne(); task1.doTaskTwo(); task1.doTaskThree(); return"task1"; }
運(yùn)行可以看到類似如下輸出:
開(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ù)本身之間不存在依賴關(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類改在為如下模式:
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 { //省略其它代碼… }
編寫測(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)文章
JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能實(shí)例
因自己負(fù)責(zé)的項(xiàng)目中需要實(shí)現(xiàn)文件上傳,所以下面下面這篇文章主要給大家介紹了關(guān)于JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能的相關(guān)資料,需要的朋友可以參考下2022-04-04Java聊天室之實(shí)現(xiàn)使用Socket傳遞音頻
這篇文章主要為大家詳細(xì)介紹了Java簡(jiǎn)易聊天室之使用Socket實(shí)現(xiàn)傳遞音頻功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下2022-10-10解決SpringCloud Feign傳對(duì)象參數(shù)調(diào)用失敗的問(wèn)題
這篇文章主要介紹了解決SpringCloud Feign傳對(duì)象參數(shù)調(diào)用失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java方法的參數(shù)傳遞機(jī)制實(shí)例詳解
這篇文章主要介紹了Java方法的參數(shù)傳遞機(jī)制,結(jié)合實(shí)例形式詳細(xì)分析了java方法參數(shù)傳遞機(jī)制原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2019-09-09解決SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find
這篇文章主要介紹了SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find a @SpringBootConfiguration,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10springBoot Junit測(cè)試用例出現(xiàn)@Autowired不生效的解決
這篇文章主要介紹了springBoot Junit測(cè)試用例出現(xiàn)@Autowired不生效的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Eclipse Web項(xiàng)目打成war包的方法圖解
當(dāng)Tomcat啟動(dòng)后該壓縮文件自動(dòng)解壓縮,war包方便了web工程的發(fā)布,那么Eclipse中如何將Web項(xiàng)目打成war包呢?下面小編通過(guò)圖文并茂的方式給大家講解下Eclipse Web項(xiàng)目打成war包的方法,一起看看吧2016-08-08