1. 程式人生 > >同步非同步、阻塞與非阻塞

同步非同步、阻塞與非阻塞

阻塞:主要針對執行緒來說,跟蹤原始碼最終會發現執行緒wait在某個方法上,等待被喚醒。在訊息通訊中,表現為來了資料後解除阻塞,比如阻塞佇列模型中的notFull.await()/notEmpty.signal()和notEmpty.await()/notFull.signal(),以及Socket阻塞通訊模型中的阻塞I/O:read/write方法要await資料到來/資料寫入完畢才可解除阻塞,繼續執行緒執行

非阻塞:不會出現wait方法。比如NIO的I/O多路複用模型,不會使用阻塞的InputStream.read或OutputStream.write,而是換一種策略,用多路複用器Selector輪詢每次可讀Channel.所謂可讀,是已經由另一方非同步寫完成的資料。如可讀,直接可從接收方網路快取中讀取,讀取耗時是確定的,不會出現無限期阻塞等待資料的情況,所耗時間是程式執行時間,不是白白await的無限期時間。如果不可讀,實際上是Channel上沒有被可讀監聽(接收方註冊,系統底層在核心收到資料後呼叫)標記為可讀,那麼會跳過對該Channel的讀寫而不是無意義阻塞等待

同步:主要針對訊息傳送和普通ACK、業務回覆訊息上報的業務情形。同步仍然是執行緒阻塞,只不過增加了私有業務的處理邏輯,在ACK或業務回覆訊息到來時由業務程式而不是語言內部實現來解除阻塞,這樣完成一個訊息的傳送和結果接收過程。

非同步:網路傳輸中的非同步模型,是核心支援的一種模式。是把資料監聽和複製到使用者快取的任務全部交給底層。上層程式只管傳送,立即返回。不用管接收,系統完成一切後會直接給出記憶體層面資料,通知程式,程式拿來資料直接用,沒有手動處理核心到使用者快取的複製過程。API中也是迴圈接收,但是非同步接收,由系統底層在核心複製到使用者完畢後回撥,回撥直接是讀寫完成後的回撥,也就是其中獲取的訊息直接是業務訊息。目前主要應用在對實時處理不太敏感的通訊領域。一般我們都用多路複用,使用程式從核心複製資料並處理,實時性和業務控制性較強

業務邏輯訊息傳送/接收中的非同步,主要指非同步上報。指傳送程式傳送一條指令後立即返回。通過在訊息體類中指定非同步回撥函式,向非同步接收程式註冊監聽。獨立執行緒的非同步接收程式通過快取和回覆訊息中的標識在接收到同一個訊息的非同步回覆後,呼叫回撥函式完成業務回覆後的業務處理邏輯。

JMS中的客戶端訊息處理同步非同步:同步是在消費者客戶端中進行同步阻塞等待(想想阻塞佇列模型,和阻塞I/O模型),來一條訊息後處理一條;非同步是向服務端(mq)註冊回撥函式,讓服務端處理,mq在接收到一條訊息後立即呼叫客戶端處理邏輯的程式碼(回撥),替客戶端完成業務資料儲存(存入客戶端的資料結構中)或處理邏輯。