You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin协程Channel未实现排队:如何串行执行processData?

问题分析与解决方案

你的代码核心问题是:每次调用call()时,都会在当前协程里直接执行processData(channel.receive())——这意味着每个call()的调用都会单独触发一次processData执行,多个并行的call()自然会让processData并行运行,完全没用到Channel的串行消费能力。

正确的做法是单独启动一个常驻协程来串行消费Channel中的消息,所有call()只负责把任务发送到Channel,不直接处理执行逻辑。

修正后的代码

class MyClass {
    private val channel: Channel<Long> = Channel()

    init {
        // 启动常驻协程,专门串行处理Channel中的任务
        CoroutineScope(Dispatchers.Default).launch {
            for (timeStamp in channel) {
                processData(timeStamp)
            }
        }
    }

    // 供其他类并行调用的公共函数,仅负责发送任务到Channel
    suspend fun call() {
        val timeStamp = System.currentTimeMillis()
        Log.i("testing", "send :$timeStamp")
        channel.send(timeStamp)
    }

    private suspend fun processData(timeStamp: Long) {
        Log.i("testing", "processData: start :$timeStamp")
        delay(5000L)
        Log.i("testing", "processData: end :$timeStamp")
    }
}

逻辑说明

  1. 初始化时启动的协程会持续循环读取Channel中的消息,每读取到一个就执行processData,必须等前一个processData执行完成,才会处理下一个消息,天然保证串行执行。
  2. call()不再自行处理任务执行逻辑,只负责生成任务并发送到Channel,多个协程并行调用call()时,只会把任务依次送入Channel等待处理。
  3. 运行后Logcat会完全符合你的预期:任务发送后先堆积在Channel中,前一个processData执行完毕才会启动下一个。

内容的提问来源于stack exchange,提问作者rgv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:35:31