如何计划Kotlin协同程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计划Kotlin协同程序相关的知识,希望对你有一定的参考价值。
我最近一直在阅读很多文章并观看很多关于Kotlin合作的视频,尽管我付出了努力,但我还是无法理解它们。
我想我终于找到了一种方法来说明我的问题:
class MyViewModel() : CoroutineScope {
override val coroutineContext = Dispatchers.Main + Job()
fun foo() = launch(handler) {
Log.e("test", "A")
}
}
class MainActivity : Activity() {
override fun onCreate() {
MainViewModel().foo()
Log.e("test", "B")
}
}
这个输出是:
E/test: B
E/test: A
我不明白这是怎么回事,我只使用一个线程(主线程)。如果我的代码按顺序执行,那么当我到达行log(B)
时... log(A)
应该已经打印出来了。
协同程序库是否在内部使用其他线程来完成此任务?这是我能提出的唯一解释,但在文档中没有找到任何说法。
PS:很抱歉把android
扔进了混合但是这段代码:
fun main() {
GlobalScope.launch(Dispatchers.Unconfined) { // launch new coroutine in background and continue
print(Thread.currentThread().name + "World!") // print after delay
}
(0 .. 1000).forEach { print(".") }
}
似乎按预期工作并打印:main @coroutine#1World!...........................
因为1 thread == sequential work
希望我的问题有道理,感谢阅读!
在引擎盖下,主调度程序使用Handler将Runnable发布到MessageQueue。基本上,它会被添加到事件队列的末尾。这意味着它将很快执行,但不会立即执行。因此,为什么“B”在“A”之前打印。
您可以在this article找到更多信息。
OP编辑(阅读上面的文章,然后阅读本文):
只是想澄清为什么上面的Android示例工作正常,万一有人还在想。
fun main() {
GlobalScope.launch(Dispatchers.Unconfined) { // launch new coroutine in background and continue
print(Thread.currentThread().name + "World!") // print after delay
}
(0 .. 1000).forEach { print(".") }
}
我们设置GlobalScope
使用UNCONFINED
调度员,这个调度员将isDispatchNeeded
设置为false
。 false
的意思是“在当前线程中安排”,这就是我们看到按顺序打印日志的原因。 UNCONFINED
不应该用于常规代码。
所有其他调度员都将isDispatchNeeded
设置为true
甚至是UI调度员。见:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/is-dispatch-needed.html
(顺便说一下,如果我们没有指定一个,则GlobalScope会使用Default
调度程序)
以上是关于如何计划Kotlin协同程序的主要内容,如果未能解决你的问题,请参考以下文章