Kotlin是否在内部延迟使用调度程序来解锁调用程序线程?

问题描述 投票:1回答:1

这是我用来学习kotlin协同程序的一些测试代码。代码按预期工作,大约需要1秒打印总和,但是现在如果我通过阻塞调用(如网络请求)替换延迟(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")


}
kotlin kotlin-coroutines
1个回答
1
投票

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

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

你应该问的问题是:“哪个调度员在这里负责?”

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

考虑到这一点:

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.