ExecutorCoroutineDispatcher 和 CoroutineDispatcher 的区别

Difference between ExecutorCoroutineDispatcher and CoroutineDispatcher

谁能从实用的角度解释一下 Kotlin Coroutine 的 ExecutorCoroutineDispatcherCoroutineDispatcher 之间的区别,即在哪些场景下使用它们?

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

不过我注意到的是,在使用 ExecutorCoroutineDispatcher (1) 时我的主要进程从未结束(使用 CoroutineDispatcher 它按预期完成 (2))。经过一些调查,我似乎应该 运行 在 ExecutorCoroutineDispatcher 上使用 close() 方法来完成主进程 (3)。使用 CoroutineDispatcher 你不必这样做,它甚至没有方法 close() (4)。 CoroutineDispatcher是不是自动关闭了?为什么我们有 ExecutorCoroutineDispatcher 的关闭过程,但 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()'
}

Is CoroutineDispatcher closed automatically? Why do we have closure process for ExecutorCoroutineDispatcher, but not for CoroutineDispatcher?

区别不在于调度程序类型,而在于底层 Java 执行器服务的配置方式。默认的共享执行器使用守护线程,这不会阻止 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")
    }
}