看看这个采用example from official Kotlin documentation:
package com.example
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我跑它会打印:
1
2
3
4
5
Done!
正如您在此处所看到的,默认情况下使用的是非缓冲通道。我们将其更改为缓冲频道:
package com.example
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce(capacity = Channel.UNLIMITED) {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我多次运行它会打印出来:
1
Done!
或
2
Done!
或只是
Done!
我认为生产者会将数据放入缓冲通道,for
循环将从中读取数据,直到它可以执行此操作(即,如果数据存在于通道或通道中,则它将被读取) 。因此,我认为for
循环应该读取缓冲通道中的所有数据,即使它已关闭。我是对的吗?
任何人都可以解释为什么缓冲通道导致生产者的这种奇怪行为?是bug吗?
P.S。
答案 0 :(得分:1)
Kotlin团队已经确认这是一个错误,opened an issue就此回答了这个问题。
该问题的描述提到它只出现在produce
构建器中并提供了一种解决方法,基本上是该方便构造的内联代码:
val producer = Channel<Int>(1)
launch(coroutineContext) {
for(i in 1..2) {
producer.send(i)
println("Sent: $i")
}
producer.close()
}