Kotlin之协程coroutine原理

Dispatchers.Main
Dispatchers.IO
Dispatchers.Default
Dispatchers.Unconfined

IO 和 Default 是用公共线程池。区别是两者对核心线程数,最大线程数的配置不一样。

Default是CPU密集型,核心线程数尽可能等于CPU核数

IO是IO密集型,核心线程数尽可能等于任务数, 最大线程数尽可能等于CPU核数和64的两者最大值。

原理是:

开启:

开启协程,编译器会把协程的作用域(代码块)编译成:SuspendLambda 类,这个类会把当前协程被挂起的点分别定义一个状态,每个挂起点对应的状态不一样。SuspendLambda  这个类,会保存当前执行的状态。这样,协程里面的代码块就分成了很多段,每一段之间有一个状态点。正常情况下,协程会按顺序执行完每一段代码。而每一个协程都对应一个Continuation,这个DispatchedContinuation 本质上是实现了Runnable的实例。最终启动,DispatchedContinuation .resumeWith()会把这个DispatchedContinuation 放进对应的线程去执行,IO和Default就会放在线程池,Main就会放在主线程对应的Handler去执行。

挂起:

当在协程里面调用了比如:withContext()等Api时,开启的新的协程就会把当前协程挂起,就会调用

SuspendLambda 里面的挂起放弃,把状态改成:coroutine_suspended,当协程的状态被改成 coroutine_suspended后,执行的流程就会被return掉,不会继续执行后面的代码。

恢复:

启动的子协程,它持有父协程的引用。当子协程执行完后,会调用父协程的SuspendLambda的 invokeSuspend(),把他状态改成运行状态,父协程就会按照状态对应的代码段位置,执行完余下代码。

Dispatchers.Unconfined

未定义线程,被哪个协程挂起,就会在哪个协程的线程上去执行。

原理,挂起它的协程执行完,会调用DispatchedContinuation.resume()方法,里面有一个逻辑是判断指派的线程是什么,如果是未定义,就会拿出当前协程对应线程的EventLoop,通过ThreadLocal去获取。然后就把Unconfined任务放在这个EventLoop去执行。这样能做到,被哪个线程挂起,就在哪个协程对应的线程上去恢复。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值