Kotlin中select关键字与Channel的用法
2022-07-08
Kotlin中Channel的使用
类似Go中的Channel,Kotlin中的Channel也可以在协程间通信
创建
最基本的声明方式:(Channel位于kotlinx.coroutines.channels.Channel)
val channel01 = Channel<Int>()
其中Int处为泛型,代表通道中放置的数据类型,取和拿都是此类型的变量
除此之外,构造函数还可以接收一个参数:
val rendezvousChannel = Channel<Int>()
val bufferedChannel = Channel<Int>(10)
val conflatedChannel = Channel<Int>(CONFLATED)
val unlimitedChannel = Channel<Int>(UNLIMITED)
含义如下:
通道类型 | 构造参数 | 通道特点 |
---|---|---|
Rendezvous | 空参 | 0尺寸buffer, send和receive要meet on time, 否则挂起. (默认类型) |
Buffered | Int值 | Int值即为通道大小, 满了之后send挂起 |
Conflated | CONFLATED | 新元素会覆盖旧元素, receiver只会得到最新元素, send永不挂起 |
Unlimited | UNLIMITED | 无限元素, send不被挂起 |
send与receive
- send:
val channel01 = Channel<Int>()
repeat(100) {
channel01.send(it)
}
- receive:
最简单的receive:
val element = channel01.receive()
除此之外,我们可以使用select关键字进行receive操作:
Kotlin中的select关键字
select在kotlin中类似when一样,可以是一个表达式,此处展示一个例子:
val str = select<String> {
channel01.onReceive { value ->
"收到数据"
}
onTimeout(1000L) {
"数据等待超时"
}
}
在上述代码中,select表达式的值赋给了str变量,其中String可以为其他任意泛型
同时,对channel01通道进行了监听,如果通道中有数据则会立即返回:“收到数据”
而onTimeOut类似when中的else,如果上面的通道监听在1000毫秒(即onTimeOut的参数值)内都没有触发,将会执行
因此如果在一秒的时间段内channel01通道中都没有数据,则会执行onTimeout部分,返回*“数据等待超时”*
把它放在一个协程中会是这样:
@OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class)
fun fun01(): Job {
return GlobalScope.launch {
var index = 0
while (true) {
val str = select<String> {
channel01.onReceive { value ->
index++
"收到来自channel01的第${index}条数据为:${value}"
}
onTimeout(1000L) {
"数据等待超时"
}
}
println(str)
}
}
}
当然,Kotlin中的select和when一样,是自带break case的