override fun resumeWith(result: Result<Any?>) {
log(result.getOrNull())
}
})
}
suspend fun suspendFunction1() = suspendCoroutine { continuation ->
val threadGroup = ThreadGroup(“thread-suspend-1”)
val threadExecutor = Executors.newSingleThreadExecutor {
Thread(threadGroup, it, “thread”)
}
threadExecutor.submit {
Thread.sleep(2000)
continuation.resume(0)
}
}
//执行结果
09:05:44:934 [main] coroutine start
09:05:46:960 [thread] 0
09:05:46:961 [thread] suspendFunction----执行之后
09:05:46:961 [thread] 1
协程框架的launch
、async aswait
、runBlocking
等等对上述的封装,使用起来更加顺手而已。
从执行的结果来看,先输出了coroutine start,之后挂起两秒钟,继续执行之后的逻辑。
那我们就用这个demo
来分析,协程的挂起与恢复是如何实现的。😮
首先我们需要分析一下挂起函数是个什么玩意儿~😮
将上述suspendFunction1
挂起函数代码转换成java
看看。
public static final Object suspendFunction1(@NotNull Continuation $completion) {
…
SafeContinuation var4 = new SafeContinuation(IntrinsicsKt.intercepted($completion));
Continuation continuation = (Continuation)var4;
int var6 = false;
ThreadGroup threadGroup = new ThreadGroup(“thread-suspend-1”);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor((ThreadFactory)(new DeepUnderstandCoroutineKt$suspendFunction1 2 2 2threadExecutor$1(threadGroup)));
threadExecutor.submit((Runnable)(new DeepUnderstandCoroutineKt$suspendFunction1$2$1(continuation)));
Object var10000 = var4.getOrThrow();
if (var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
DebugProbesKt.probeCoroutineSuspended($completion);
}
return var10000;
}
final class DeepUnderstandCoroutineKt$suspendFunction1$2$1 implements Runnable {
// $FF: synthetic field
final Continuation $continuation;
public final void run() {
Thread.sleep(2000L);
Continuation var1 = this.$continuation;
Integer var2 = 0;
boolean var3 = false;
Companion var4 = Result.Companion;
boolean var5 = false;
var1.resumeWith(Result.constructor-impl(var2));
}
DeepUnderstandCoroutineKt$suspendFunction1$2$1(Continuation var1) {
this.$continuation = var1;
}
}
看得出,suspend函数反编译之后,会自动将一个Continuation
作为参数传递进函数,且返回类型为object
。😮
简单看一下,将Continuation
作为参数传递给了IntrinsicsKt.intercepted($completion)
。IntrinsicsKt
在java
平台的具体实现在IntrinsicsJvm
文件中。而intercepted
的源码如下所示:
pu