繁体   English   中英

Kotlin:如何在没有 runBlocking 的情况下桥接阻塞代码和异步代码?

[英]Kotlin: How to bridge between blocking and asynchronous code without runBlocking?

我正在从事一个涉及我想并行运行的计算密集型任务的项目。 为此,我使用多个async语句来运行任务并awaitAll等待所有线程完成计算。

suspend fun tasks() {
   coroutineScope {
      val result = List (10) {
         async { 
            // do stuff
         }
      }.awaitAll()
   }
}

我的问题是如何在并行运行的代码和常规同步代码之间建立桥梁。

我尝试使用runBlocking ,但这似乎一个接一个地运行所有async任务,因此违背了使用协程的全部目的。 我让它工作的唯一方法是一直使用suspend函数直到main function,但这对我来说不合适,因为我依赖第三方库从常规函数调用我的代码。

有没有办法从常规函数调用挂起函数,同时仍然保持它们并行运行的能力?

子任务顺序运行的原因是默认情况下runBlocking()利用调用它的线程来创建单线程调度程序并使用它运行所有协程。 如果您的协程从不挂起,它们将被顺序调用。

为了使用另一个调度程序,我们只需要将它传递给runBlocking()

runBlocking(Dispatchers.Default) { ... }

但是,如果您还没有使用协程并且您不打算暂停,而只是执行 CPU 密集型任务,那么我不确定您是否完全可以从协程中受益。 协程主要用于执行经常需要等待的任务,因此我们可以利用它们的挂起和恢复功能。 如果我们需要经常分叉和加入,它们很有用。 但如果我们只需要并行化 CPU 计算,那么使用执行器的经典方法就可以了。

此外,在使用runBlocking()进行桥接时,注意不要从协程本身调用它。 我们不能在协程上下文中运行时阻塞线程。 它可能导致严重的性能问题甚至死锁。 如果您调用runBlocking() ,然后在其中调用堆栈深处的某处再次调用您的一个桥接器,您将遇到问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM