用 Kotlin 协程替代 Thread 并行加载多测线雷达图
背景
多测线雷达图加载,原来用 ExecutorService + Thread:一条测线一个任务,结果靠回调或者 Future 收。线程数基本靠拍脑袋,取消靠一个 volatile 标志位,异常处理各写各的,并行度也把握不好。串行加载几条测线的时候界面就干等着,体感很慢。
换成协程
换成 Kotlin 协程以后,多测线并行加载就剩这么一段:
suspend fun loadMultiScanLines(files: List<RadarFile>): List<RadarData> = coroutineScope { |
比 Thread 那套舒服的地方:所有 async 任务都挂在同一个 coroutineScope 底下,scope 一取消、子任务跟着取消,不用再手写标志位;async { ... }.awaitAll() 一眼就能看出是”并行几个、等全部完成”,比 Future.get 套回调清晰多了;哪个子任务抛异常会往上冒泡到 scope,配上 SupervisorJob 还能做到”一个挂了不连累其他”;读文件用 Dispatchers.IO、刷 UI 用 Dispatchers.Main,中间 withContext 切一下,线程边界很清楚。
配合生命周期
协程 scope 绑到 ViewModel 的生命周期上,组件销毁时统一取消,就不会再出现”界面关了、后台还在读文件,读完回调去刷一个早就销毁的 UI”这种空指针了。
在我看来,协程相对 Thread 最大的好处就是结构化并发和取消传播,并行加载这段代码从几十行缩到几行,可读、还不容易写错。后来导出、批量重算这些要并发的地方,也都统一到这套写法上了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 CYK's Blog!
评论
