首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在kotlin中不阻塞主线程的并行调用

在kotlin中不阻塞主线程的并行调用
EN

Stack Overflow用户
提问于 2022-01-31 21:58:52
回答 1查看 350关注 0票数 1

我正在学习kotlin协同和作用域,无法理解如何通过不阻塞主线程来触发并行调用。正如您在下面的示例中所看到的,两个调用是并行触发的,但是对.awaitAll()的调用似乎阻塞了主线程,因为我希望“I‘s阻塞消息”将打印在“1.1.Current线程.”之前。消息。这是实现这类查询的正确方法吗?

当前产出:

主螺纹主

.(5秒后).

1.当前线程DefaultDispatcher-worker-1

1.当前线程DefaultDispatcher-worker-3

我被堵住了

预期产出:

主螺纹主

我被堵住了

.(5秒后).

1.当前线程DefaultDispatcher-worker-1

1.当前线程DefaultDispatcher-worker-3

代码语言:javascript
复制
class FindItinerariesComposable(private val providers: List<FindItineraries>) : FindItineraries {
    override suspend fun itinerariesForOriginDestination(origin: String, destination: String): List<Itinerary> {
        println("Main thread ${Thread.currentThread().name}")
        return coroutineScope {
            val stream = providers.stream()
                .map {
                    async {
                        it.itinerariesForOriginDestination(origin, destination)
                    }
                }
                .toList()
                .awaitAll()
                .flatten()
            println("I'm blocked")
            stream
        }
    }
}


class FindItinerariesInFlightProvider(private val httpClient: HttpClient) : FindItineraries {

    override suspend fun itinerariesForOriginDestination(origin: String, destination: String): List<Itinerary> {
        withContext(Dispatchers.IO) {
            delay(5000)
            println("1.Current thread  ${Thread.currentThread().name}")
        }
        return listOf(Itinerary("bue", "MIA", "TEST"))
    }
}

fun main() = runBlocking<Unit> {
    val service = FindItinerariesComposable(listOf(FindItinerariesInFlightProvider(HttpClient()),
        FindItinerariesInFlightProvider(HttpClient())))
    launch {
        service.itinerariesForOriginDestination("BUE", "MIA")
    }
}
EN

回答 1

Stack Overflow用户

发布于 2022-02-01 06:55:22

你好像也想吃蛋糕。

在让主线程继续执行任何进一步的任务之前,您希望得到主线程上所有这些调用的结果。

您也不想阻塞主线程。

如果需要后者,则必须引入并发性,其中主线程执行其他任务,并且不需要这些结果才能继续。

这可能意味着你正在做的事情的设计发生了根本性的变化。如果您有任何依赖于这些结果的代码,那么您将不得不添加更多的代码,这些代码使用了一些暂存值或模型值,直到实际的结果可用为止。您还必须将当前接收结果并对其进行操作的任何代码移动到协同线中。

下面是一个大纲:

代码语言:javascript
复制
fun main() {
    val service = initializeService()
    val myScope = CoroutineScope()
    myScope.launch {
        val itineraries = service.itinerariesForOriginDestination("BUE", "MIA")
        // do things with itineraries
    }
    // do other things, don't let the main function end
    myScope.cancel() // do this at the very end, when you no longer
                     // need coroutines
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70933310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档