Kotlin 延迟是否在内部使用调度程序来取消阻止调用线程?



这是我用来学习 kotlin 协程的一些测试代码。代码按预期工作,打印总和大约需要 1 秒,但现在如果我用像网络请求这样的阻塞调用替换 delay(1000),那么代码大约需要 10 秒来打印总和(每次调用大约需要 1 秒),但是如果我将网络调用包装在 withContext 中并使用 IO 调度程序,则需要 1 秒来打印总和, 因为它在不同的线程上运行。延迟函数是否使用某种调度程序来解锁线程?


suspend fun asyncDoubleFn(num: Int): Int {
delay(1000)
return num * 2
}

fun main() = runBlocking {
launch {
val tt = measureTimeMillis {
val results = mutableListOf<Deferred<Int>>()
for (num in 0..10) {
val result = async { asyncDoubleFn(num + 1) }
results.add(result)
}
val sum = results.map { it.await() }.reduce { acc, i -> acc + i }
println("[SUM]: $sum")
}
println("[TT]: $tt")
}

launch {
println("Another coroutine")
}
println("Main Code")

}

延迟函数是否使用某种调度程序来解锁线程?

不仅仅是delay.所有可挂起的功能都与调度程序交互。

您应该问的问题是:"哪个调度员负责这里?

答案是:runBlocking安装自己的调度程序,调度到调用它的线程。代码中的launchasync都继承了它。

考虑到这一点:

如果我用像网络请求这样的阻塞调用替换 delay(1000),那么代码大约需要 10 秒来打印总和(每次调用大约需要 1 秒)

每个阻塞调用将保留调度程序的单个线程。在被阻止时,它将无法执行任何其他工作。

但是如果我将网络调用包装在withContext并使用IO调度程序,则打印总和需要 1 秒,因为它在不同的线程上运行

是的,这改变了调度程序,问题解决了。

那么,delay是做什么的呢?它挂起当前协程(async启动的协程)并将控制权返回给调度程序,调度程序现在可以继续恢复循环并启动下一个协程。

相关内容

  • 没有找到相关文章

最新更新