暂停功能如何不阻塞主线程?

时间:2020-04-07 04:27:30

标签: async-await kotlin-coroutines suspend

协程在Dispatchers上启动.Main在挂起时不会阻塞主线程。 这是什么意思? 所以当暂停功能在主线程上启动时,如果有一些行需要花费更长的时间,它会自动分配给新线程吗? 这令人困惑吗?

2 个答案:

答案 0 :(得分:2)

挂起的函数会像任何普通函数一样在一个线程上运行,但是当它切换到另一个线程时不会阻塞主线程。

一个正常的函数,当从主线程切换到后台线程时,它必须阻塞主线程,因为它执行后不知道从哪里继续。

    ...
    val result = getResult()  // This blocks the main thread due to join
    use(result);

fun getResult(): String {
    var result: String = ""
    val t = Thread(Runnable {
        ...
        result = "woohoo"
    })
    t.start()
    t.join()  // Main thread is waiting for the result to return it
    return result
}

但是当一个挂起的函数切换线程时,它不会阻塞主(前一个)线程,因为它知道执行后从哪里继续。

launch(Dispatchers.Main) {
    ...
    val result = getResult()  // This will not block the main thread
    use(result)
}

suspend fun getResult(): String = withContext(Dispatchers.IO) {
    ...
    "woohoo"
}

答案 1 :(得分:0)

Dispatchers.Main是一个CoroutineContext,它将协程分派到主线程中,但是当协程本身挂起时,即通过更改上下文或线程或其他原因,则“主线程变为空闲”,而Continuation引擎盖下的物体负责随后继续执行。

由于在挂起时主线程上没有正在运行的任务,因此它是免费的,并且可以由上下文(分派器)承担其他任务,因此被记录为未阻塞。