1. 程式人生 > >[Java 18_001] Asynchronous 和 Non-blocking 的比較

[Java 18_001] Asynchronous 和 Non-blocking 的比較

Spring Framework 5 中添加了 Spring WebFlux 框架,在其文件介紹中,出現了 non-blocking 的概念:

The reactive stack, web framework, Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports Reactive Streams back pressure, and runs on servers such as Netty, Undertow, and Servlet 3.1+ containers.

我不理解 non-blocking 和 asynchronous 的區別,本文主要是學習參考這個 stackoverflow 的帖子的內容,主要參考 Daniel Earwicker, artm 和 Nikolai Fetissov 的答案:

  • Blocking 和 synchronous 意味著相同的事物:呼叫了一個 API,這個函式會一直佔用執行緒直到它執行完畢或返回某些結果。
  • Non-blocking 意味著如果不能立即返回結果,API立即返回一個 error 並且不做其他事情。所以必須採用某種方法來知道 API 是否準備好被呼叫(使用一種有效的方法來模擬一個 wait,而避免在一個單執行緒的緊湊迴圈(tight loop)內進行人為輪詢(manual polling)。non-blocking 涉及 輪詢(polling)
    的概念,也就是間隔一段時間再重複檢查所呼叫的 API 是否滿足呼叫條件或返回結果。
  • Asynchronous 意味著 API 總是立即返回,已經啟動了一種後臺執行來處理你的請求,所以必須有某種方法來獲得 API 執行結果。asynchronous涉及 並行(in parallel)的概念,也就是另外一個執行緒。

另一位網友 Yves 的回答也非常好:
synchronous / asynchronous 描述的是兩個模組(modules)間的關係。
blocking / non-blocking 是描述一個模組的情況。
他舉了一個例子:

“I”: a
“bookstore”: b
a asks b: do you have a book named “c++ primer”?

  • blocking: 在 b 回答 a 之前,a 會在那兒一直等待 b 的答案。現在 a(one module)是阻塞的(blocking)。a 和 b 是兩個執行緒,兩個程序還是一個執行緒或者一個程序?我們並不知道。
  • non-blocking: 在 b 回答 a 之前,a 會離開那裡,之後每隔兩分鐘,a 會返回那裡尋找 b 的答案。這時 a(one module)是非阻塞的(non-blocking),a 和 b 是兩個執行緒還是兩個程序還是一個程序我們並不知道,但是我們可以確認 a 和 b 不可能是一個執行緒。
  • synchronous: 在 b 回答 a 之前,a會一直在那裡等待 b 的答案。這意味著在 b 完成它的工作返回答案之前,a 不能繼續。這是我們說:a 和 b (two modules)是同步的,a 和 b 是兩個執行緒還是兩個程序還是一個執行緒或一個程序?我們並不知道。
  • asynchronous: 在 b 回答 a 之前,a 離開這裡並且 a 可以做其他的工作,當 b 完成工作產生答案時,b 會通知 a:“嗨!我有答案了”。然後在 a 空閒的時候, a 將來到 b 這兒拿到那本書。現在我們可以說:a 和 b (兩個模組)是非同步的(asynchronous)。a 和 b 是兩個執行緒和兩個程序還是一個程序?我們並不知道,但是我們確信 a 和 b 不可能是一個執行緒。

參考資料

[1] spring framework 官方文件:https://docs.spring.io/spring/docs/5.0.2.RELEASE/spring-framework-reference/web-reactive.html#spring-webflux
[2] stackoverflow 論壇貼:https://stackoverflow.com/questions/2625493/asynchronous-vs-non-blocking