SpringBoot用@Async注解實(shí)現(xiàn)異步任務(wù)
異步調(diào)用是相對(duì)于同步調(diào)用而言的,同步調(diào)用是指程序按預(yù)定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調(diào)用則無(wú)需等待上一步程序執(zhí)行完即可執(zhí)行。
如何實(shí)現(xiàn)異步調(diào)用?多線程,這是很多人第一眼想到的關(guān)鍵詞,沒(méi)錯(cuò),多線程就是一種實(shí)現(xiàn)異步調(diào)用的方式。
在非spring目項(xiàng)目中我們要實(shí)現(xiàn)異步調(diào)用的就是使用多線程方式,可以自己實(shí)現(xiàn)Runable接口或者集成Thread類,或者使用jdk1.5以上提供了的Executors線程池。
StrngBoot中則提供了很方便的方式執(zhí)行異步調(diào)用。
異步接口的使用場(chǎng)景耗時(shí)比較長(zhǎng),任務(wù)比較多的接口。比方說(shuō),文件下載,大文件下載比較耗時(shí),這個(gè)時(shí)候就可以使用異步接口。
項(xiàng)目示例已上傳至GitHub,可見(jiàn)github項(xiàng)目地址。
在解釋異步調(diào)用之前,我們先來(lái)看同步調(diào)用的定義;同步就是整個(gè)處理過(guò)程順序執(zhí)行,當(dāng)各個(gè)過(guò)程都執(zhí)行完畢,并返回結(jié)果。 異步調(diào)用則是只是發(fā)送了調(diào)用的指令,調(diào)用者無(wú)需等待被調(diào)用的方法完全執(zhí)行完畢;而是繼續(xù)執(zhí)行下面的流程。
例如, 在某個(gè)調(diào)用中,需要順序調(diào)用 A, B, C三個(gè)過(guò)程方法;如他們都是同步調(diào)用,則需要將他們都順序執(zhí)行完畢之后,方算作過(guò)程執(zhí)行完畢; 如B為一個(gè)異步的調(diào)用方法,則在執(zhí)行完A之后,調(diào)用B,并不等待B完成,而是執(zhí)行開(kāi)始調(diào)用C,待C執(zhí)行完畢之后,就意味著這個(gè)過(guò)程執(zhí)行完畢了。
@Async介紹基于@Async標(biāo)注的方法稱為異步方法,方法在執(zhí)行的時(shí)候,將會(huì)在獨(dú)立的線程中被執(zhí)行,調(diào)用者無(wú)需等待它的完成,即可繼續(xù)其他的操作。使用時(shí)在SpringBoot主配置類中開(kāi)啟異步即可。
@EnableAsync@SpringBootApplicationpublic class SpringBootAsyncTestApplication {無(wú)返回值異步方法
@Asyncpublic void asyncMethodWithNoReturnType() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('asyncMethodWithNoReturnType...');}
使用方法比較簡(jiǎn)單,編寫(xiě)一個(gè)測(cè)試方法并加上@Async注解即可。
含返回值異步方法@Asyncpublic Future<String> asyncMethodWithReturnType() { try { Thread.sleep(3000); return new AsyncResult<String>('success'); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('asyncMethodWithReturnType...'); return null;}
返回值利用Future泛型接口實(shí)現(xiàn)。
Future是對(duì)于具體的 Runnable 或者 Callable 任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成、獲取結(jié)果的接口,必要時(shí)可以通過(guò)get方法獲取執(zhí)行結(jié)果,該方法會(huì)阻塞直到任務(wù)返回結(jié)果,包含了以下幾個(gè)方法。
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
1.cancel方法的作用是取消任務(wù),取消任務(wù)成功則返回true,反之返回false。參數(shù) mayInterruptIfRunning 表示是否允許取消正在執(zhí)行卻沒(méi)有執(zhí)行完畢的任務(wù)。
運(yùn)行cancel方法取消任務(wù)時(shí):
i.若任務(wù)已完成:則無(wú)論 mayInterruptIfRunning 為 true 或 false,此方法都返回 false,即取消已經(jīng)完成的任務(wù)都會(huì)返回false。
i.若任務(wù)正在執(zhí)行:
mayInterruptIfRunning 設(shè)置為 true,則返回true。 mayInterruptIfRunning 設(shè)置為false,則返回false。iii.如果任務(wù)未執(zhí)行,則無(wú)論mayInterruptIfRunning為true還是false,都返回true。
2.isCancelled方法的作用是判斷任務(wù)是否被取消成功,若在任務(wù)正常完成前被取消,則返回 true。
3.isDone方法的作用是判斷任務(wù)是否已經(jīng)完成,若任務(wù)已完成,則返回true。
4.get()方法的作用是獲取執(zhí)行結(jié)果,注意此方法會(huì)產(chǎn)生阻塞,等到任務(wù)執(zhí)行完畢后才能獲得執(zhí)行結(jié)果。
5.get(long timeout, TimeUnit unit)方法的作用同樣是獲取執(zhí)行結(jié)果,若在指定時(shí)間內(nèi)還未獲取到執(zhí)行結(jié)果,則返回null。
編寫(xiě)測(cè)試接口編寫(xiě)/callWithNoReturnType和/callWithReturnType接口用于查看異步任務(wù)的執(zhí)行過(guò)程。
@RestControllerpublic class AsyncController { @Autowired AsyncService asynSerivce; @GetMapping('/callWithNoReturnType') public String callWithNoReturnType() { asynSerivce.asyncMethodWithNoReturnType(); return 'success'; } @GetMapping('/callWithReturnType') public String callWithReturnType() { Future<String> future=asynSerivce.asyncMethodWithReturnType(); try { return future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return 'fail'; }
運(yùn)行項(xiàng)目后使用Postman進(jìn)行接口測(cè)試,分別給/callWithNoReturnType和/callWithReturnType接口發(fā)送Get請(qǐng)求,調(diào)用無(wú)返回值的異步方法asyncWithNoReturnType時(shí),會(huì)立即返回返回值。但調(diào)用含返回值異步方法asyncWithReturnType時(shí),由于我們調(diào)用了get()方法,會(huì)在等待3000毫秒后,才返回返回值。
到此這篇關(guān)于SpringBoot用@Async注解實(shí)現(xiàn)異步任務(wù)的文章就介紹到這了,更多相關(guān)SpringBoot @Async異步內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. Python如何批量生成和調(diào)用變量2. windows服務(wù)器使用IIS時(shí)thinkphp搜索中文無(wú)效問(wèn)題3. Python基于requests實(shí)現(xiàn)模擬上傳文件4. ASP.NET MVC實(shí)現(xiàn)橫向展示購(gòu)物車5. 通過(guò)CSS數(shù)學(xué)函數(shù)實(shí)現(xiàn)動(dòng)畫(huà)特效6. python利用opencv實(shí)現(xiàn)顏色檢測(cè)7. Python 中如何使用 virtualenv 管理虛擬環(huán)境8. ASP.Net Core(C#)創(chuàng)建Web站點(diǎn)的實(shí)現(xiàn)9. Python sorted排序方法如何實(shí)現(xiàn)10. Python獲取B站粉絲數(shù)的示例代碼
