注册

实现穿梭栈帧的魔法--协程

1. 协程-穿梭栈帧的魔法


协程的特性是代码中调用一次,实际会执行2次,第一次如果不满足条件先return一个状态,当满足条件的时候线程池会回调该方法执行第二次,而且还具有单例特性(指该函数第一次和第二次执行期间共享同一个上下文),妥妥的操作栈帧的魔法师。


2. 如何实现协程


前提:本文仅探讨kotlin协程实现


其实在反编译suspend函数反编译后就能知道协程的实现原理(以下)


github.com/yujinyan/ko…


//协程代码
//suspend fun foo() :Any{
// delay(3000L)
// val value =getCurrentTime()
// Log.e("TAG", "result is $value")
//}
//等价代码
@suspend fun foo() {
foo(object : Continuation<Any> {
override fun resumeWith(result: Result<Any>) {
val value = result.getOrThrow()
Log.e("TAG", "result is $value")
}
})
}

@suspend fun foo(continuation: Continuation<Any>): Any {
class FooContinuation : Continuation<Any> {
var label: Int = 0

override fun resumeWith(result: Result<Any>) {
val outcome = invokeSuspend()
if (outcome === COROUTINE_SUSPENDED) return
continuation.resume(result.getOrThrow())
}

fun invokeSuspend(): Any {
return foo(this)
}
}

val cont = (continuation as? FooContinuation) ?: FooContinuation()
return when (cont.label) {
0 -> {
cont.label++
//异步延时任务
AppExecutors.newInstance().otherIO.execute {
Thread.sleep(3000L)
val value = getCurrentTime()
cont.resume(value)
}
COROUTINE_SUSPENDED
}
1 -> 1 // return 1
else -> error("shouldn't happen")
}
}

核心就是函数内匿名内部类的巧用,真的很妙



作者:zjw-swun
链接:https://juejin.cn/post/7039233157823987726
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册