我正在使用Ktor撰寫 Kotlin 服務器- 我的請求處理程式是使用 Kotlin 協程撰寫的。
我的理解是每個請求處理程式都在 Ktor 的執行緒池上運行,由于協程的輕量級/可暫停特性,該執行緒池包含的執行緒比傳統的每個請求 1 個執行緒的服務器框架的池大小要少得多。偉大的!
我遇到的問題是我的應用程式仍然需要與一些阻塞資源(JDBC 資料庫連接池)進行互動,但我的理解是,如果我只是直接從請求協程中呼叫這些阻塞 API,我最終會遇到活性問題——因為我最終可能會阻塞用于處理我的請求的所有執行緒!不是很好。
由于我對 Kotlin 和協程的世界還比較陌生,我想知道這里是否有人可以給我一些關于處理這種情況的最佳方法的提示。
我在Dispatchers.IO其他地方看到過幾次參考。這是否被認為是管理這些阻塞呼叫的最佳方式?這方面有什么好的例子嗎?
我嘗試使用的 API 確實允許通過傳遞Executor. 理想情況下,我還可以將這些呼叫包裝在一個方便、慣用的 Kotlin API 中,用于suspend處理事務。
uj5u.com熱心網友回復:
你都理解正確。在大多數情況下,你不應該在協程中阻塞執行緒。Dispatchers.IO你提到了一個例外。這是處理阻塞代碼的標準方法,并且非常易于使用:
withContext(Dispatchers.IO) {
// blocking code
}
withContext()是一個掛起函式,所以你可以把上面想成將阻塞轉換為掛起的方式。然而,Dispatchers.IO它并沒有真正發揮任何作用——它只是使用了一個更大的執行緒池,專門用于阻塞。我相信默認情況下它最多創建 64 個執行緒。
如果您需要執行多個并行阻塞操作,通常最好創建自己的執行緒池,以免阻塞應用程式的其他組件。
如果 IO 庫提供異步 API,那么通常最好使用它而不是阻塞 API。但是,在許多情況下,庫通過管理自己的內部執行緒池來提供異步 API 以進行阻塞。在這種情況下,使用異步 API 和使用阻塞 APIDispatchers.IO非常相似。Dispatchers.IO可能會更好,因為它在所有 IO 操作中重復使用相同的 IO 執行緒,并且它可以與指定用于 CPU 計算的執行緒池部分共享執行緒 ( Dispatchers.Default)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/411488.html
標籤:
