挂起函数如何不阻塞主线程?

Vik*_*dey 7 suspend async-await kotlin-coroutines

在 Dispatchers.Main 上启动的协程在挂起时不会阻塞主线程。这是什么意思?那么,当挂起函数在主线程上启动时,如果某些行需要更长的时间,它是否会自动分配给新线程?这很令人困惑?

小智 7

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

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

    ...
    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
}
Run Code Online (Sandbox Code Playgroud)

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

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

suspend fun getResult(): String = withContext(Dispatchers.IO) {
    ...
    "woohoo"
}
Run Code Online (Sandbox Code Playgroud)


Ani*_*ahu 1

Dispatchers.Main是一个 CoroutineContext,它将协程分派到主线程中,但是当协程本身挂起时,即通过更改上下文或线程或其他原因,“主线程变得空闲”,并且幕后的对象Continuation负责随后继续执行。

由于挂起时主线程上没有运行任何任务,因此它是自由的,并且能够通过上下文(调度程序)执行另一个任务,因此被记录为不被阻塞。