ExecutorCoroutineDispatcher 和 CoroutineDispatcher 的区别

Myr*_*lav 5 dispatcher executor kotlin-coroutines

有人可以从实际角度解释一下 Kotlin CoroutineExecutorCoroutineDispatcher和Kotlin Coroutine 之间的区别,即在哪些场景下使用一个协程来对抗另一个协程?CoroutineDispatcher

到目前为止,我一直在使用Dispatchers,但是(据我所知)它不能给我一个后台线程。这就是我使用的原因newSingleThreadExecutor()

但我注意到的是,我的主进程在使用ExecutorCoroutineDispatcher(1)时永远不会结束( CoroutineDispatcher它按预期完成(2))。经过一番调查后,我似乎应该运行方法close()ExecutorCoroutineDispatcher完成主流程(3)。由于 CoroutineDispatcher您不必这样做,因此它甚至没有方法close()(4)。是CoroutineDispatcher自动关闭的吗?为什么我们有 for 的关闭流程 ExecutorCoroutineDispatcher,但没有 for CoroutineDispatcher

下面是我用于测试的代码:

fun main() = runBlocking<Unit> {
    val dispatcher1 = Executors.newSingleThreadExecutor().asCoroutineDispatcher() // (1) <-- main process runs indefinitely w/o closing dispatcher1 (3)
    val dispatcher2 = Dispatchers.Unconfined // (2)
    println("Start")

    launch(dispatcher1) {
        println("Child")
        delay(1000)
        printInfo(coroutineContext, this)
    }.join()

    println("End")
    dispatcher1.close() // (3) <-- need to close dispatcher1 for the main process to finish, otherwise it runs indefinitely
//    dispatcher2.close() // (4) <-- dispatcher2 doesn't have method 'close()'
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 6

CoroutineDispatcher自动关闭的吗?为什么我们有 for 的关闭流程ExecutorCoroutineDispatcher,但没有 for CoroutineDispatcher

区别不在于调度程序类型,而在于底层 Java Executor Service 的配置方式。默认共享执行器使用守护线程,这不会阻止 JVM 关闭。如果您愿意,您可以为自己的执行者获得相同的结果:

val myExecutor = Executors.newSingleThreadExecutor { task ->
    Thread(task).also { it.isDaemon = true }
}

val myDispatcher = myExecutor.asCoroutineDispatcher()

suspend fun main() {
    withContext(myDispatcher) {
        println("On my dispatcher")
    }
}
Run Code Online (Sandbox Code Playgroud)