本文主要记录Kotlin中suspend关键字和async函数的使用及源码解读

书接上回Kotlin协程的使用以及launch源码解读

代码示例

下文中代码均以此示例为例,不再赘述。

初始源码为:

fun main(args: Array<String>) {
    GlobalScope.launch {
        println("scope start")
        val job = withContext(Dispatchers.IO) {
            delay(1000)
            println("with end")
            "1"
        }
        val asyncJob  = async{
            println("async start")
            delay(2000)
            "async end"
        }
        val res = asyncJob.await()
        println("scope end $res")
    }
    println("Main end")
}

输出结果:
Main end
scope start
with end
async start
scope end async end

这里有几个问题:

  1. Main end为什么会最先打印?(launch源码中已经解释了为啥)
  2. 为什么协程能实现asyncJob中的异步调用一定在job中的异步调用执行完毕后再开始执行呢?
  3. 为什么协程最后的scope end打印一定会在asyncJob调用await完毕后再执行?

为了搞懂第2个问题我们先看下suspend源码里是怎么实现的

suspend源码

参考文章

Kotlin协程实现原理:挂起与恢复