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

遍历Kotlin Channel时跳过偶数元素问题排查

Kotlin Channels 迭代丢失偶数元素问题

问题代码

class TestChannels {
    @Test
    fun testChannels() {
        runBlocking {
            val someNumbers = Channel<Int>(UNLIMITED)
            repeat(100) {
                someNumbers.send(it)
            }
            someNumbers.close()
            for (number in someNumbers) {
                println(number)
            }
        }
    }
}

预期输出

1
2
3
4
5
6
7
8
9
10

实际输出

1
3
5
7
9

版本差异

  • Kotlin 1.7.21:使用LinkedListChannel实现UNLIMITED通道,代码运行正常,无元素丢失
  • Kotlin 1.8.22:使用BufferedChannel实现UNLIMITED通道,出现偶数元素丢失的异常情况

解决方案

该问题是Kotlin 1.8.x版本中BufferedChannel的迭代器实现bug导致的,可通过以下方式规避:

  1. 改用consumeEach消费通道
    consumeEach是Kotlin协程通道推荐的消费方式,能正确读取所有元素:

    runBlocking {
        val someNumbers = Channel<Int>(UNLIMITED)
        repeat(100) {
            someNumbers.send(it)
        }
        someNumbers.close()
        someNumbers.consumeEach {
            println(it)
        }
    }
    
  2. 使用receiveCatching循环读取
    通过手动循环调用receiveCatching直到通道关闭,确保所有元素被读取:

    runBlocking {
        val someNumbers = Channel<Int>(UNLIMITED)
        repeat(100) {
            someNumbers.send(it)
        }
        someNumbers.close()
        while (true) {
            val result = someNumbers.receiveCatching()
            if (result.isFailure) break
            println(result.getOrNull())
        }
    }
    
  3. 降级到Kotlin 1.7.21
    暂时回退到无问题的版本,等待官方修复该bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:42:52