Kotlin:深度理解协程挂起恢复实现原理。纯源码分析。

​ 看得出,suspend函数反编译之后,会自动将一个Continuation作为参数传递进函数,且返回类型为object。😮

​ 简单看一下,将Continuation作为参数传递给了IntrinsicsKt.intercepted($completion)IntrinsicsKtjava平台的具体实现在IntrinsicsJvm文件中。而intercepted的源码如下所示:

public actual fun Continuation.intercepted(): Continuation =

(this as? ContinuationImpl)?.intercepted() ?: this

​ 这里不再深追,如果您熟悉协程框架的话,这里其实返回了Continuation的拦截器,依旧是Continuation类型,如果不存在拦截器,其实还是返回的自身。我们上面的写法,没有拦截器,返回的就是自身。最终将返回的Continuation传递给了SafeContinuation

​ 省略掉线程池的代码,看到最后调用了SafeContinuationgetOrThrow函数,我们来看一下这个代码(具体实现在SafeContinuationJvm文件):😮

internal actual class SafeContinuation

internal actual constructor(

private val delegate: Continuation,

initialResult: Any?

) : Continuation, CoroutineStackFrame {

@PublishedApi

internal actual constructor(delegate: Continuation) : this(delegate, UNDECIDED)

@Volatile

private var result: Any? = initialResult

internal actual fun getOrThrow(): Any? {

var result = this.result // atomic read

if (result === UNDECIDED) {

if (RESULT.compareAndSet(this, UNDECIDED, COROUTINE_SUSPENDED)) return COROUTINE_SUSPENDED

result = this.result // reread volatile var

}

}

​ 先简单看一下SafeContinuation构造器,我们会调用它的副构造器,将**continuation赋值给delegate。同时赋值initialResultUNDECIDED**。所以此时result == UNDECIDED

​ 所以调用getOrThrow之后,就会走if (RESULT.compareAndSet(this, UNDECIDED, COROUTINE_SUSPENDED)) return COROUTINE_SUSPENDEDresult设置为COROUTINE_SUSPENDED,同时返回COROUTINE_SUSPENDED

​ 所以最终suspendFunction1函数会返回COROUTINE_SUSPENDED标志,代表挂起

​ 接下来我们分析一下传递给线程执行的代码如何走到恢复呢?我们看一下run()里面的代码,其实就是在恢复的时候,调用了SafeContinuationresumeWith函数,我们看一下resumeWith的代码:

public actual override fun resumeWith(result: Result) {

while (true) { // lock-free loop

val cur = this.result // atomic read

when {

cur === UNDECIDED -> if (RESULT.compareAndSet(this, UNDECIDED, result.value)) return

cur === COROUTINE_SUSPENDED -> if (RESULT.compareAndSet(this, COROUTINE_SUSPENDED, RESUMED)) {

delegate.resumeWith(result)

return

}

else -> thro

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值