[英]Kotlin Flow vs Channel for Concurrent Processing
我正在嘗試構建一個與消息傳遞 API 交互的簡單多線程處理應用程序。 目前,我已經將這個API抽象成一個流程如下:
fun myAbstractedAPI(): Flow<Message> = callbackFlow<Message> {
repeat(threadCount) {
launch {
while (true) {
val message = getMessageFromApiAsync.await()
trySendBlocking(it)
}
}
}
}
awaitClose { channel.close() }
}
這會同時輪詢我的 API 並將消息發送到流中。 到目前為止一切都很好...
然后,我可以在我的主要功能中與此流程進行交互,如下所示:
myAbstractedAPI.collect {
// do something with the Messages
}
我當然可以收集流程並啟動協程來處理流程,但我覺得這可能會讓我陷入瓶頸,因為主線程需要迭代流程來分配工作。
也許渠道是更好的解決方案? 例如,如果myAbstractedAPI()
生成了一個通道,那么我可以啟動 N 個通道消耗線程,這些線程可以獨立於主線程運行。
擔心單個線程迭代流以將工作分配給工作線程的“瓶頸”是否是一個有效的問題。 如果是這樣——基於渠道的方法更好嗎?
我當然可以收集流程並啟動協程來處理流程,但我覺得這可能會讓我陷入瓶頸,因為主線程需要迭代流程來分配工作。
這反映了對協程如何工作的根本誤解。
第一:即使您只在 Dispatchers.Main 上運行,您也不會阻塞或占用整個線程。 每當沒有要處理的元素時,運行收集協程的線程池就會做其他事情。 你不會遇到瓶頸。
其次,您不必使用主線程,除非您手動選擇這樣做,否則您很可能不會使用主線程。 最有可能的是,您將在某個線程池上運行,例如 Dispatchers.Default,它不包括主線程。
確實,在此設計中,您無法同時處理流中的多個元素。 但是,如果您想這樣做,合適的方法是使用 flatMapMerge 或其他一些同時處理流元素的 API,而不是放棄流。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.