0

一般來說,圍繞被動異步代碼異步處理請求(play,akka,netty等)存在巨大的噱頭。 以這種方式執行代碼時,建議不要在任何地方阻止和使用異步庫。 如果我正確理解這一點,這種方式,而不是爲每個請求創建一個線程,我們最終有線程執行者爲這些庫帶來的執行的多個部分(主要處理請求,異步調用服務執行程序,異步數據庫驅動程序執行程序等)如何實現異步數據庫庫?

這種方式執行最終分裂成多個線程(=在多個執行者中)。 這些異步庫如何實現以便帶來任何好處?因爲在異步數據庫驅動程序具有執行程序的情況下,該程序運行一個簡單地等待數據庫答案的線程,所以我認爲它不會帶來任何好處。我們最終會等待任何東西,只需創建額外的線程來執行,等待不會有任何幫助。還是呢?

+1

這些庫使用固定大小的線程池和異步IO。他們不會爲每個請求打開一個新線程。 –

+0

而且你知道,這不是一個好問題。您列出了各種不同的框架;你在找什麼?有人向你詳細解釋這些工作是如何在內部工作的? – GhostCat

回答

1

我認爲關於異步庫的常見誤解是因爲想象它們如何工作的最簡單方法是考慮如何使用可用的工具編寫庫的語言來實現它們該語言 - 通常會導致思考「如果DoWorkAsync必須等待其他事情完成,那麼DoWorkAsync肯定會佔用線程,直到完成工作」。這聽起來很浪費,而且唯一的好處是異步庫處理管理將用於等待工作的線程。

但是,這些異步方法實際上可以與低級別通信形式一起使用,而不是在Java中直接訪問。

當異步工作必須處理某種形式的IO時,它不能立即從中獲取數據(包括各種各樣的東西,比如IPC,磁盤訪問和網絡訪問 - 等等,通過擴展,數據庫調用),操作系統將與設備驅動程序進行通信,該驅動程序具有對異步調用的內置低級別支持,以便它可以開始工作,然後觸發某種中斷以告知操作系統何時完成工作。在此期間,不需要託管線程繼續存在(並繼續吸取資源) - 當設備驅動程序正在處理工作時,不需要等待它的線程。當設備驅動程序指示其異步工作已完成時,操作系統會傳遞此信息,並使用一個線程繼續工作。

以上是一個非常簡單的解釋(並且可能在各種方式上都不準確),但希望它可以跨越 - 線程不需要等待異步數據,它可以解決您的原始問題。

有這個優秀的(和簡潔)的文章中瞭解更多信息:There Is No Thread(這是關於.NET但同樣的原則也適用)