Kotlin协程介绍(二)实现原理

通过Kotlin协程介绍(一)我们了解到协程可以让顺序的代码实现CPS的效果,实际上协程的本质就是在编译期将顺序代码变为CPS。协程用suspend关键字声明一个挂起函数

suspend fun delay(time: Int)

挂起函数经过编译后,在jvm里会变成一个CPS:

//Continuation用来实现CPS的回调
interface Continuation<T> {
    void resumeWith(Result<T> result)
}

void delay(Int time, Continuation<Int> continuation)

delay通过continuation.resumeWith回调执行后续代码。挂起函数编译生成的CPS,不是一个简单的回调,而是一个状态机模型:

suspend fun simpleCoroutine() {
    val start = System.currentTimeMillis()
    println("start")
    delay(1000) // 挂起点
    println("end ${System.currentTimeMillis() - start}")
}

上面的代码编译器变为一个状态机:

class SimpleCoroutine {
    var label = 0
    var start = 0L

    fun resume() {
        when (label) {
            0 -> {
                start = System.currentTimeMillis()
                println(“start")
                label++
                delay(1000, this)
            }
            1 -> {
                println("end ${System.currentTimeMillis() - start}”)
                label++
            }
        }
    }
}

label代表当前状态,每一个挂起点和初始挂起点对应的 Continuation 都会转化为一种状态。随着挂起点的增加,只会增加状态,但不会增加回调嵌套的深度。挂起函数将执行过程分为多个 Continuation 片段,并且利用状态机的方式保证各个片段是顺序执行的。

发布了11 篇原创文章 · 获赞 1 · 访问量 274

猜你喜欢

转载自blog.csdn.net/vitaviva/article/details/104092566