Kotlin协程结合Channel使用时并发修改与代码差异问题咨询
问题1解答:参考代码中的allUsers不会被并发修改
参考代码里allUsers的读写操作完全只在父协程的repeat循环中执行,所有通过launch启动的子协程仅负责将单仓库的贡献者列表发送到Channel,不会触碰allUsers变量。Channel的receive是串行执行的,每次只会取出一个子协程发送的单仓库数据,再更新allUsers,全程没有多协程并发修改allUsers的场景,不存在并发修改问题。
问题2解答:你的代码错误原因就是并发修改共享变量导致的
两段代码的核心差异:
- 官方实现的汇总逻辑完全收敛在父协程执行,子协程仅负责产出单仓库的贡献者数据,没有任何共享可变变量的读写操作。
- 你的代码把共享可变变量
contributors放在多个子协程中直接修改,修改完成后才将全量汇总列表发送到Channel。
错误原因:
你使用的Default dispatcher会将多个子协程分配到不同的线程并行执行,contributors是多协程共享的可变变量,读-改-写的过程没有任何同步保护:
比如协程A刚读到contributors的当前值,还没完成新值赋值,协程B也读到了同样的旧值,最终其中一个协程的修改结果会被直接覆盖,导致部分仓库的贡献者数据丢失。同时你发送到Channel的列表本身就是被并发修改后的错误值,最终拿到的结果自然不符合预期。
内容的提问来源于stack exchange,提问作者Tendai
相关产品推荐
相关产品推荐

