协程简单上手(线程切换)

上一篇文章中我们分析了挂起函数的本质(状态机),以及查看编译器为我们生成的类里面是如何借用状态机实现的"挂起",那么在实际coding中我们该如何使用协程呢?

协程作用域

所有协程都必须在一个协程作用域CoroutineScope内运行。一个 CoroutineScope 管理一个或多个相关的协程。

协程如何开启呢?可以通过launch和async函数创建协程并将其函数主体的执行分派给相应的调度程序

调度程序也就是launch和async的函数主体会运行在哪个线程中。比如

javascript 复制代码
launch(Dispatchers.IO){
     //协程主体函数
}

Dispatchers.IO 指示此协程应在为 I/O 操作预留的线程上执行。

那么当协程内部还需要切换线程的时候呢?典型的场景比如开启协程获取数据需要进行不同的线程切换: 这时候可以使用withContext

javascript 复制代码
withContext(Dispatchers.IO) {
            // IO线程运行
        }

当withContext运行完成之后会自动恢复调用withContext的线程中。

如何看阻塞

同一协程体内的代码是阻塞的,但是协程体里面又开启了一个协程,两个协程不影响各自运行,但父协程取消的时候默认子协程也会取消。

取消协程运行

不管是通过launch还是async开启的协程,其都会返回一个Job对象,调用该Job对象的cancel即可取消协程。协程内部会通过抛出一个取消异常终止运行。

上面是针对某一个具体的协程取消,如果我想全部取消呢?比如界面销毁的时候,通过调用协程域的取消,位于这个协程域里面的协程都会取消。 Android为我们自动提供了一个viewmodelScope,他可以在配置改变引起的销毁重建时自动取消开启协程不用担心泄漏问题。

CoroutineContext

CoroutineContext 使用以下元素集定义协程的行为:代表该协程的上下文信息比如协程的名称,协程的调度器(Dispatcher),异常处理等

  • Job:控制协程的生命周期。
  • CoroutineDispatcher:将工作分派到适当的线程。
  • CoroutineName:协程的名称,可用于调试。
  • CoroutineExceptionHandler:处理未捕获的异常。

协程如何测试

开启协程

runTest 是用于测试的协程构建器。相比于正式编码的时候使用的是launch和async。使用此构建器可封装包含协程的任何测试。

必须使用指定调度器

通过TestDispatchers调度器来指定协程的运行线程,相比于正式编码使用的是Dispatchers.IO,Dispatchers.Main,Dispatchers.Default。 除 runTest 创建的顶级协程外,如果代码还创建了新的协程,则需要选择适当的 TestDispatcher,以控制这些新协程的调度方式,设置新协程的调度器。 TestDispatchers是用于测试的 [CoroutineDispatcher] 实现。由于多线程下的测试是不可预测的,所以正式编码中出现的withContext切换线程应换成单线程的方式因为这样将会使得结果可预测,所以再项目中不能使用硬编码去设置调度器Dispatchers,应该使用注入的方式如果是测试注入TESTDispatchers,如果是正式注入正常的Dispatcher。

相关推荐
DKPT4 小时前
ZGC和G1收集器相比哪个更好?
java·jvm·笔记·学习·spring
低客的黑调5 小时前
为你的项目选择一个适合的[垃圾收集器]
java·jvm·算法
xu_yule9 小时前
Linux_14(多线程)线程控制+C++多线程
java·开发语言·jvm
豆奶特浓610 小时前
Java面试生死局:谢飞机遭遇在线教育场景,从JVM、Spring Security到AI Agent,他能飞吗?
java·jvm·微服务·ai·面试·spring security·分布式事务
Boop_wu12 小时前
[Java EE] 多线程进阶(JUC)(2)
java·jvm·算法
3***312114 小时前
java进阶1——JVM
java·开发语言·jvm
打工人你好2 天前
如何设计更安全的 VIP 权限体系
java·jvm·安全
unclecss2 天前
把 Spring Boot 的启动时间从 3 秒打到 30 毫秒,内存砍掉 80%,让 Java 在 Serverless 时代横着走
java·jvm·spring boot·serverless·graalvm
q***2512 天前
java进阶1——JVM
java·开发语言·jvm
zlpzlpzyd2 天前
jvm 偏向锁禁用以及移除
jvm