获取以下两个代码示例(分别取自Kotlin文档和Coroutines库自述):
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(2000)
println("World")
}
println("Hello")
}
在Kotlin >= 1.3.0中,可以将main()
函数标记为suspend
可实现,并直接使用coroutineScope
。
import kotlinx.coroutines.*
suspend fun main() = coroutineScope {
launch {
delay(2000)
println("World")
}
println("Hello")
}
两者产生的产出相同:
Hello
World
这两种方法在功能上有什么不同吗?如果是,他们是什么?
发布于 2022-04-30 09:37:50
runBlocking()
和coroutineScope()
在功能上非常相似。它们都暂停当前的执行,直到内部协同线完成。区别在于,runBlocking()
是从一个常规的不可挂起的代码中执行的,所以它通过阻塞等待,而coroutineScope()
是从可挂起的上下文中使用的,所以它挂起。
这种差异使他们在内部做了很多不同的事情。runBlocking()
必须首先初始化整个协同机制,然后才能执行可挂起的lambda。coroutineScope()
可以访问现有的协同上下文,因此它只调度要执行和挂起的内部lambda。
现在,suspend fun main()
只是Kotlin编译器提供的一种“快捷方式”,可以使coroutines应用程序更容易初始化。在内部,它在真正的主功能和可挂起的主要功能之间创建了一座桥梁。它生成一个独立的main()
函数,它是不可挂起的,是“真实”的主函数。这个函数初始化一个协同线并使用内部runSuspend()
实用程序来执行您的suspend fun main()
。这里描述了这一点:https://github.com/Kotlin/KEEP/blob/master/proposals/enhancing-main-convention.md#implementation-details-on-jvm-1
这两种方法开始一个协同应用程序是非常相似的,你可以选择根据你的口味。一个值得注意的区别是,runBlocking()
使用当前的“主”线程创建了一个调度程序。suspend fun main()
也使用主线程执行,但它没有指定dispatcher,所以每当您使用coroutineScope()
时,它都会切换到Dispatchers.Default
。因此,您的runBlocking()
示例使用单线程调度程序,而coroutineScope()
示例使用多线程Dispatchers.Default
。然而,在选择这两种方法时,不应真正考虑到这种差异。我们随时都可以很容易地更换调度员。
https://stackoverflow.com/questions/72066943
复制相似问题