這篇文章主要介紹了Spring中@Async用法詳解及簡單實例的相關資料,需要的朋友可以參考下
Spring中@Async用法
引言: 在Java應用中,絕大多數情況下都是透過同步的方式來實現交互處理的;但是在處理與第三方系統交互的時候,容易造成響應遲緩的情況,之前大部分都是使用多執行緒來完成此類任務,其實,在spring 3.x之後,就已經內建了@Async來完美解決這個問題,本文將完成介紹@Async的用法。
1. 何為非同步呼叫?
在解釋非同步呼叫之前,我們先來看同步呼叫的定義;同步是整個處理過程順序執行,當各個過程都執行完畢,並且回傳結果。 非同步呼叫則只是發送了呼叫的指令,呼叫者無需等待被呼叫的方法完全執行完畢;而是繼續執行下面的流程。
例如, 在某個調用中,需要順序調用A, B, C三個過程方法;如他們都是同步調用,則需要將他們都順序執行完畢之後,方算作過程執行完畢; 如B為一個非同步的呼叫方法,則在執行完A之後,呼叫B,並不等待B完成,而是執行開始呼叫C,待C執行完畢之後,就表示這個過程執行完畢了。
2. 常規的非同步呼叫處理方式
在Java中,一般在處理類似的場景之時,都是基於創建獨立的執行緒去完成對應的非同步呼叫邏輯,透過主執行緒和不同的執行緒之間的執行流程,從而在啟動獨立的執行緒之後,主執行緒繼續執行而不會產生停滯等待的情況。
3. @Async介紹
在Spring中,基於@Async標註的方法,稱為非同步方法;這些方法將在執行的時候,將會在獨立的執行緒中被執行,呼叫者無需等待它的完成,即可繼續其他的操作。
如何在Spring中啟用@Async
以Java設定為基礎的啟用方式:
#@Configuration @EnableAsync public class SpringAsyncConfig { ... }##
##
<task:executor id="myexecutor" pool-size="5" /> <task:annotation-driven executor="myexecutor"/>
## 啟用方式,設定如下:
@Async //标注使用 public void asyncMethodWithVoidReturnType() { System.out.println("Execute method asynchronously. " + Thread.currentThread().getName()); }
以上就是兩個定義的方式。
4. 基於@Async無回值呼叫 範例如下:@Async public Future<String> asyncMethodWithReturnType() { System.out.println("Execute method asynchronously - " + Thread.currentThread().getName()); try { Thread.sleep(5000); return new AsyncResult<String>("hello world !!!!"); } catch (InterruptedException e) { // } return null; }
# 使用的方式非常簡單,一個標註即可解決所有的問題。
5. 基於@Async回傳值的呼叫
# 範例如下:public void testAsyncAnnotationForMethodsWithReturnType() throws InterruptedException, ExecutionException { System.out.println("Invoking an asynchronous method. " + Thread.currentThread().getName()); Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType(); while (true) { ///这里使用了循环判断,等待获取结果信息 if (future.isDone()) { //判断是否执行完毕 System.out.println("Result from asynchronous process - " + future.get()); break; } System.out.println("Continue doing something else. "); Thread.sleep(1000); } }
# 以上範例可以發現,傳回的資料類型為Future類型,其為一個介面。具體的結果類型為AsyncResult,這個是需要注意的地方。
呼叫傳回結果的非同步方法範例:public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor { private AsyncTaskExecutor executor; public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) { this.executor = executor; } ////用独立的线程来包装,@Async其本质就是如此 public void execute(Runnable task) { executor.execute(createWrappedRunnable(task)); } public void execute(Runnable task, long startTimeout) { /用独立的线程来包装,@Async其本质就是如此 executor.execute(createWrappedRunnable(task), startTimeout); } public Future submit(Runnable task) { return executor.submit(createWrappedRunnable(task)); //用独立的线程来包装,@Async其本质就是如此。 } public Future submit(final Callable task) { //用独立的线程来包装,@Async其本质就是如此。 return executor.submit(createCallable(task)); } private Callable createCallable(final Callable task) { return new Callable() { public T call() throws Exception { try { return task.call(); } catch (Exception ex) { handle(ex); throw ex; } } }; } private Runnable createWrappedRunnable(final Runnable task) { return new Runnable() { public void run() { try { task.run(); } catch (Exception ex) { handle(ex); } } }; } private void handle(Exception ex) { //具体的异常逻辑处理的地方 System.err.println("Error during @Async execution: " + ex); } }
分析: 這些取得非同步方法的結果訊息,是透過不停的檢查Future的狀態來取得目前的非同步方法是否執行完畢來實現的。
6. 基於@Async呼叫中的異常處理機制
在非同步方法中,如果出現異常,對於呼叫者caller而言,是無法感知的。如果確實需要進行異常處理,則按照以下方法來處理: 1. 自訂實作AsyncTaskExecutor的任務執行器 在這裡定義處理特定例外狀況的邏輯和方式。 2. 設定由自訂的TaskExecutor取代內建的任務執行器 範例步驟1,自訂的TaskExecutor<task:annotation-driven executor="exceptionHandlingTaskExecutor" scheduler="defaultTaskScheduler" /> <bean id="exceptionHandlingTaskExecutor" class="nl.jborsje.blog.examples.ExceptionHandlingAsyncTaskExecutor"> <constructor-arg ref="defaultTaskExecutor" /> </bean> <task:executor id="defaultTaskExecutor" pool-size="5" /> <task:scheduler id="defaultTaskScheduler" pool-size="1" />
分析: 可以發現其是實現了AsyncTaskExecutor, 用獨立的線程來執行具體的每個方法操作。在createCallable和createWrapperRunnable中,定義了異常的處理方式和機制。
handle()就是未來我們需要關注的異常處理的地方。 設定檔中的內容:rrreee
分析: 這裡的設定使用自訂的taskExecutor來取代缺省的TaskExecutor。
7. @Async調用中的事務處理機制
# 在@Async標註的方法,同時也適用了@Transactional進行了標註;在其呼叫資料庫操作之時,將無法產生事務管理的控制,原因就在於其是基於非同步處理的操作。 那該如何為這些作業新增事務管理呢?可以將需要事務管理操作的方法放置到非同步方法內部,在內部被呼叫的方法上新增@Transactional.###### 例如: 方法A,使用了@Async/@Transactional來標註,但是無法產生事務控制的目的。 ###方法B,並使用了@Async來標註, B中呼叫了C、D,C/D分別使用@Transactional做了標註,則可實現事務控制的目的。
8. 總結
透過上述的描述,應該對@Async所使用的方法和注意事項了。
以上就是Spring中@Async用法詳解及簡單實例介紹的內容,更多相關內容請關注PHP中文網(www.php.cn)!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版
中文版,非常好用

Dreamweaver Mac版
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載
最受歡迎的的開源編輯器