在 Dispatchers.Main 上启动的协程在挂起时不会阻塞主线程。这是什么意思?因此,当在主线程上启动挂起函数并有一些较长的行时,它是否会自动分配到新线程中?这很令人困惑。
一个挂起的函数会在一个线程上运行,就像普通函数一样,但是当它切换到另一个线程时,不会阻塞主线程。
普通函数在从主线程切换到后台线程时,必须阻塞主线程,因为它不知道执行后从哪里继续。
...
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"
}
Dispatchers.Main
是一个 CoroutineContext,它将协程调度到主线程中,但当协程本身暂停时,即通过更改上下文或线程或其他某些原因,则“主线程变为空闲状态”,底层的 Continuation
对象负责在此之后继续执行。
由于挂起时没有任务在主线程上运行,因此它是空闲的,并且能够通过上下文(Dispatcher)接受另一个任务,因此被记录为非阻塞状态。