J.J. Huang   2019-04-21   Spring Boot   瀏覽次數:次  

SpringBoot - 第三十三章 | @Async 實現異步調用

📑 目錄
  1. 同步調用/異步調用
  2. 同步調用範例
    1. 建立 SyncTask
    2. 建立 測試案例
    3. 測試結果
  3. 異步調用範例
    1. 建立 AsyncTask
    2. 建立 測試案例
    3. 測試結果
  4. 異步回調範例
    1. 建立 CompleteAsyncTask
    2. 建立 測試案例
    3. 測試結果

同步、異步我們經常用到,在Java中我們大部分時間都是在做同步編程,因為Java天生就是同步的,然而我們在某些​​場景下是需要考慮吞吐量和延遲,也就是我們經常提起的性能問題,那異步避免不了會被提起。

同步調用/異步調用

  • 同步調用:指程序按照定義順序依次執行,每一行程序都必須等待上一行程序執行完成之後才能執行。
  • 異步調用:指程序在順序執行時,不等待異步調用的語句返回結果就執行後面的程序。

同步調用範例

建立 SyncTask

建立 測試案例

測試結果

SpringBoot - 第三十三章 - 圖 1 (01)

任務一、二、三順序的執行完了,所以說doTaskOne、doTaskTwo、doTaskThree三個函數依照順序執行完成。​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​​‌​​‌‌‌​​‌​​‌‌​​​​​​‌‌​‌​​​​‌‌​​‌​​​‌‌​​​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌‌​​‌‌​​‌‌​​‌‌


異步調用範例

上面的同步調用雖然順利的執行完了三個任務,但是可以看到執行時間比較長,若這三個任務本身之間不存在依賴關係,可以並發執行的話,同步調用在執行效率方面就比較差,可以考慮通過異步調用的方式來並發執行。

我們只需要通過使用@Async註解就能簡單的將原來的同步函數變為異步函數。

建立 AsyncTask

建立 測試案例

測試結果

SpringBoot - 第三十三章 - 圖 2 (02)​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​​‌​​‌‌‌​​‌​​‌‌​​​​​​‌‌​‌​​​​‌‌​​‌​​​‌‌​​​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌‌​​‌‌​​‌‌​​‌‌

目前doTaskOne、doTaskTwo、doTaskThree三個函數的時候已經是異步執行了。主程序在異步​​調用之後,主程序並不會理會這三個函數是否執行完成了,由於沒有其他需要執行的內容,所以程序就自動結束了,導致了不完整或是沒有輸出任務相關內容的情況。

注意: @Async所修飾的函數不要定義為static類型,這樣異步調用不會生效。

SpringBoot - 第三十三章 - 圖 3 (03)​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​​‌​​‌‌‌​​‌​​‌‌​​​​​​‌‌​‌​​​​‌‌​​‌​​​‌‌​​​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌‌​​‌‌​​‌‌​​‌‌

這邊將程式的註解移除,讓同步與異步的一起執行測試,可以看到異步的程序沒有被結束,正好可以觀察異步的調用狀態。


異步回調範例

為了讓doTaskOne、doTaskTwo、doTaskThree能正常結束,假設我們需要統計一下三個任務並發執行共耗時多少,這就需要等到上述三個函數都完成調動之後記錄時間,併計算結果。

那麼我們如何判斷上述三個異步調用是否已經執行完成呢?我們需要使用CompletableFuture來返回異步調用的結果。​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​​‌​​‌‌‌​​‌​​‌‌​​​​​​‌‌​‌​​​​‌‌​​‌​​​‌‌​​​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌‌​​‌‌​​‌‌​​‌‌

建立 CompleteAsyncTask

建立 測試案例

測試結果

SpringBoot - 第三十三章 - 圖 4 (04)

可以看見透過異步調用,讓任務一、二、三併發執行,且可以做回調來判斷任務完成狀況決定後續事務處理,例:總完成時間。

註:以上參考了
SpringCreating Asynchronous Methods 文章。
DZoneSpring Boot: Creating Asynchronous Methods Using @Async Annotation 文章。
程序猿DDSpring Boot中使用@Async实现异步调用 文章。
nealma.comSpring-Boot(十七) Async Of Spring Boot
(十八)SpringBoot2.0使用@Async实现异步调用​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​​‌​​‌‌‌​​‌​​‌‌​​​​​​‌‌​‌​​​​‌‌​​‌​​​‌‌​​​‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌​​​​‌‌​​‌‌​​‌‌​​‌‌