为什么协程第一个在调用方线程上运行,但在第一个挂起点之后在“ Dispatchers.Unconfined”中的DefaultExecutor上运行?

时间:2019-02-14 16:48:24

标签: kotlin kotlin-coroutines

下面的代码打印

import kotlinx.coroutines.*

    fun main() = runBlocking<Unit> {
        launch(Dispatchers.Unconfined) {
            // not confined -- will work with main thread
            println("thread ${Thread.currentThread().name}")
            delay(500)
            println("thread ${Thread.currentThread().name}")
        }
    }

第一次在调用者线程上运行,但是在第一个挂起点之后,它在“ Dispatchers.Unconfined”中的DefaultExecutor上运行

 thread main
 thread kotlinx.coroutines.DefaultExecutor

2 个答案:

答案 0 :(得分:1)

阅读Dispatchers.Unconfined的描述,它准确地解释了这种行为:

  

协程分派器,不限于任何特定线程。它会在当前调用框架中立即执行协程的初始继续,并让协程在相应的挂起函数使用的任何线程中恢复,而无需强制执行任何特定的线程策略。 注意:请格外小心,不要用于一般代码

答案 1 :(得分:0)

Unconfined调度程序没有与之关联的线程。在几乎所有情况下,协程都在用户调用continuation.resume()的线程上恢复。

在显示的特定情况下,您调用标准函数delay,因此Kotlin必须在内部处理其暂停和恢复。为此,它会维护一个计划的线程池,并向该线程池提交恢复任务,并按照您指定的延迟进行计划。

Unconfined调度程序仅在特殊的情况下有用,在这种情况下,您需要编写自己的基础结构并希望控制协程恢复的线程。基本上,这会使整个调度程序机制短路。