当前位置:网站首页>Source code analysis of kotlin collaborative process startup
Source code analysis of kotlin collaborative process startup
2022-07-28 23:09:00 【ZZ White Dragon】
Concept :
CoroutineScope
* Defines a scope for new coroutines. Every **coroutine builder** (like [launch], [async], etc)
* is an extension on [CoroutineScope] and inherits its [coroutineContext][CoroutineScope.coroutineContext]
* to automatically propagate all its elements and cancellation.
*
Define the scope of the new process . Each collaboration builder ( Such as launch 、 async etc. ) All are CoroutineScope An extension of , And inherit it coroutineContext To automatically propagate all its elements and cancel .
* Every coroutine builder (like [launch], [async], etc)
* and every scoping function (like [coroutineScope], [withContext], etc) provides _its own_ scope
* with its own [Job] instance into the inner block of code it runs.
* By convention, they all wait for all the coroutines inside their block to complete before completing themselves,
* thus enforcing the structured concurrency. See [Job] documentation for more details.
*
Each collaboration builder ( Such as launch 、 async etc. ) And each scope function ( Such as coroutineScope 、 withContext etc. ) Both provide their own scope and their own Job example . By convention , they Wait for all the processes in its block to complete Finish yourself again , thus Enforce structured concurrency .
The routine code starts the process
CoroutineScope(Dispatchers.IO).launch {
}
Enclosed kotlin bytecode decomplie Code
BuildersKt.launch$default(CoroutineScopeKt.CoroutineScope((CoroutineContext)Dispatchers.getIO()), (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object var1) {
Object var2 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch(this.label) {
case 0:
ResultKt.throwOnFailure(var1);
return Unit.INSTANCE;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new <anonymous constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), 3, (Object)null);
launch start-up kotlin The source implementation is as follows :
Parameters :
context - It's co-operative CoroutineScope.coroutineContext Additional content of context .
start - Co process startup options . The default value is CoroutineStart.DEFAULT .
block - The coroutine code that will be called in the context of the scope provided .
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
// 1. Create context for new collaboration . It does not specify another scheduler or ContinuationInterceptor Installed at Dispatchers.Default ,
// And add optional support for debugging tools ( When open ).
val newContext = newCoroutineContext(context)
//2 establish coroutine , It's usually StandaloneCoroutine
val coroutine = if (start.isLazy)
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
//3 Start the coroutines , CoroutineStart.DEFAULT By default startCoroutineCancellable .
coroutine.start(start, coroutine, block)
return coroutine
}
CoroutineScope spread function launch
1.newCoroutineContext
@ExperimentalCoroutinesApi
public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
val combined = coroutineContext + context
val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
return if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null)
debug + Dispatchers.Default else debug
}
1. Will launch Method passed in context And CoroutineScope Medium context combined
2. If combined There are no interceptors in the , A default interceptor will be passed in , namely Dispatchers.Default, This also explains why we There will be a default thread switching effect when there is no incoming interceptor
2. establish Continuation
val coroutine = if (start.isLazy)
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
By default , We will create a StandloneCoroutine
It is worth noting that , This coroutine In fact, it's our collaborative process complete, Callback after success , Not the synergist itself
And then call coroutine.start, This indicates the start of the process
3. Start the process
coroutine.start(start, coroutine, block)
It's actually calling theta
// Be similar to startCoroutineCancellable , But for the collaboration that has been created . fatalCompletion Only use when the interceptor throws an exception
internal fun Continuation<Unit>.startCoroutineCancellable(fatalCompletion: Continuation<*>) =
runSafely(fatalCompletion) {
intercepted().resumeCancellableWith(Result.success(Unit))
}
Next call
@InternalCoroutinesApi
public fun <T> Continuation<T>.resumeCancellableWith(
result: Result<T>,
onCancellation: ((cause: Throwable) -> Unit)? = null
): Unit = when (this) {
is DispatchedContinuation -> resumeCancellableWith(result, onCancellation)
else -> resumeWith(result)
}
3.1 resumeCancellableWith
// We inline it to save an entry on the stack in cases where it shows (unconfined dispatcher)
// It is used only in Continuation<T>.resumeCancellableWith
@Suppress("NOTHING_TO_INLINE")
inline fun resumeCancellableWith(
result: Result<T>,
noinline onCancellation: ((cause: Throwable) -> Unit)?
) {
val state = result.toState(onCancellation)
if (dispatcher.isDispatchNeeded(context)) {
_state = state
resumeMode = MODE_CANCELLABLE
dispatcher.dispatch(context, this)
} else {
executeUnconfined(state, MODE_CANCELLABLE) {
if (!resumeCancelled(state)) {
resumeUndispatchedWith(result)
}
}
}
}
边栏推荐
- Symbol符号类型
- WebApplicationType#deduceFromClasspath
- Hands on Teaching of servlet use (1)
- MySQL数据库的基本概念以及MySQL8.0版本的部署(一)
- 安全狗入选《云安全全景图2.0》多个细项
- Migration from IPv4 to IPv6
- Improvement 18 of yolov5: the loss function is improved to alpha IOU loss function
- PCA学习
- Improvement 17 of yolov5: cnn+transformer -- integrating bottleneck transformers
- 一份来自奎哥的全新MPLS笔记,考IE必看 ----尚文网络奎哥
猜你喜欢

Summary of common formula notes for solving problems in Higher Mathematics

Performance optimized APK slimming

Sqlilabs-3 (entry notes)

MySQL数据库的基本概念以及MySQL8.0版本的部署(一)

Target detection notes - overview and common data sets
![[3D target detection] 3dssd (I)](/img/84/bcd3fe0ba811ea79248a5f50b15429.png)
[3D target detection] 3dssd (I)

Recurrent neural network (RNN)

18 diagrams, intuitive understanding of neural networks, manifolds and topologies

A new paradigm of distributed deep learning programming: Global tensor

Improvement 17 of yolov5: cnn+transformer -- integrating bottleneck transformers
随机推荐
Target detection notes SSD
Introduction to structure
Es personal arrangement of relevant interview questions
[radar] radar signal online sorting based on kernel clustering with matlab code
DirectX repair tool download (where is exagear simulator package)
console.log()控制台显示...解决办法
Summary of core functions of software testing tool Fiddler postman JMeter charlse
RuntimeError: set_ sizes_ contiguous is not allowed on a Tensor created from .data or .detach().
Nacos配置热更新的4种方式、读取项目配置文件的多种方式,@value,@RefreshScope,@NacosConfigurationProperties
c语言进阶篇:指针(二)
【MongoDB】MongoDB数据库的基础使用,特殊情况以及Mongoose的安装和创建流程(含有Mongoose固定版本安装)
Performance optimized APK slimming
【图像分割】基于方向谷形检测实现静脉纹路分割附MATLAB代码
Multi activity disaster recovery construction after 713 failure of station B | takintalks share
Servlet的使用手把手教学(一)
无代码开发平台管理后台入门教程
[image segmentation] vein segmentation based on directional valley detection with matlab code
今年联发科5G芯片出货有望达到5000万套!
芯华章宣布完成超2亿A轮融资,全面布局EDA2.0研发
There are four ways for Nacos to configure hot updates and multiple ways to read project configuration files, @value, @refreshscope, @nacosconfigurationproperties