channel用于協(xié)程之間的通訊,使用send和receive往通道里寫(xiě)入或者讀取數(shù)據(jù),2個(gè)方法為非阻塞掛起函數(shù),channel是熱流,不管有沒(méi)有訂閱者都會(huì)發(fā)送。
Channel的簡(jiǎn)單使用
val channel = Channel<Int>()
launch {
channel.send(111)
}
launch {
println("receive:" + channel.receive())
}
打印 receive:111
Channel 默認(rèn)是0容量的buffer
send是個(gè)掛起函數(shù),發(fā)送到通道,如果通道buffer已滿(mǎn),就會(huì)掛起調(diào)用者
例如:
val channel = Channel<Int>()
launch {
channel.send(111)
println("sendbefore:222")
channel.send(222)
println("sendafter:222")
channel.send(333)
}
launch {
println("receive:" + channel.receive())
}
打印
receive:111
sendbefore:222
channel.send(222) 發(fā)送到通道后,通道滿(mǎn)了,調(diào)用者的協(xié)程被掛起,所以 println("sendafter:222")不執(zhí)行了
recevie調(diào)用時(shí),如果通道里不為空,就從通道里把元素拿出來(lái),并且從通道里移除元素,如果通道元素為空,則掛起調(diào)用者,等通道有元素后 才會(huì)執(zhí)行
例如
val channel = Channel<Int>()
launch {
delay(5000)
channel.send(111)
}
launch {
println("receive:before")
println("receive:" + channel.receive())
println("receive:after")
}
打印
2022-08-17 16:21:24.918 7723-7723/com.kemai.myapplication I/System.out: receive:before
2022-08-17 16:21:29.924 7723-7723/com.kemai.myapplication I/System.out: receive:111
2022-08-17 16:21:29.924 7723-7723/com.kemai.myapplication I/System.out: receive:after
receive:before和 receive:111 間隔了5秒
receive時(shí) 通道里沒(méi)有元素,被掛起,5秒后發(fā)送了元素,繼續(xù)執(zhí)行
Channel迭代獲取
lifecycleScope.launch {
channel.send(1)
channel.send(2)
}
lifecycleScope.launch {
for(x in channel){
println(x)
}
println("receive:end" )
}
打印
1
2
接受者一直在等待,所以不打印 receive end
在send完畢后,調(diào)用channel.close即可執(zhí)行完畢,打印receive end
Channel的四種類(lèi)型
Rendezvous channel(默認(rèn)類(lèi)型): 0尺寸buffer,send是個(gè)掛起函數(shù),發(fā)送到通道,如果通道buffer已滿(mǎn),就會(huì)掛起調(diào)用者,這個(gè)0buffer,發(fā)送一個(gè),如果沒(méi)人接收,調(diào)用者就被掛起
Buffered channel:指定元素大小,發(fā)送當(dāng)buffer滿(mǎn)了后Send會(huì)被掛起。
Conflated channel: 新元素會(huì)覆蓋舊元素,receiver只會(huì)得到最新元素,Send永不掛起。
Unlimited channel: buffer無(wú)限,Send不被掛起。
例子:
1 Rendezvous channe
val rendezvousChannel = Channel<Int>(Channel.RENDEZVOUS)
lifecycleScope.launch {
rendezvousChannel.send(1)
println("after send 1111")
rendezvousChannel.send(2)
println("after send 2222")
}
lifecycleScope.launch {
println(rendezvousChannel.receive())
println("receive:end")
}
//打印1
//receive:end
//after send 1111
//rendezvousChannel 發(fā)送了1后,接受了1,繼續(xù)發(fā)送2,因?yàn)閎uffer是0,所以滿(mǎn)了,2沒(méi)人接收,所以調(diào)用者被掛起,沒(méi)有打印after send 2222
2 Buffered channel
val bufferedChannel = Channel<Int>(2)
lifecycleScope.launch {
bufferedChannel.send(1)
println("after send 1111")
bufferedChannel.send(2)
println("after send 2222")
bufferedChannel.send(3)
println("after send 3333")
bufferedChannel.send(4)
println("after send 4444")
}
lifecycleScope.launch {
println(bufferedChannel.receive())
println("receive:end")
}
//打印
//after send 1111
//after send 2222
//1
//receive:end
//after send 3333
//bufferedChannel(2) 發(fā)送了1后,接受了1,繼續(xù)發(fā)送2 3 4,因?yàn)閎uffer是2,發(fā)送了2和3后,所以滿(mǎn)了,2沒(méi)人接收,所以調(diào)用者被掛起,沒(méi)有打印after send 4444
3 Conflated channel
val conflatedChannel = Channel<Int>(Channel.CONFLATED)
lifecycleScope.launch {
for (x in 1..10) {
conflatedChannel.send(x)
}
}
lifecycleScope.launch {
println(conflatedChannel.receive())
println("receive:end")
}
//打印10 只會(huì)接收最新值 但是在2次send之間delay1毫秒,會(huì)取第一次的,應(yīng)該機(jī)制是send被掛起之前的最新值,掛起后 就算另外一批次的發(fā)送了
4 Unlimited channel
val unlimitedChannel = Channel<Int>(Channel.UNLIMITED)
lifecycleScope.launch {
for (x in 1..10) {
unlimitedChannel.send(x)
println(x)
}
}
lifecycleScope.launch {
println(unlimitedChannel.receive())
println(unlimitedChannel.receive())
println("receive:end")
}
//打印send 1-10 只會(huì)接收最新值 receive 1-2 receive end, send方法不會(huì)掛起,因?yàn)閎uffer無(wú)限大,不會(huì)被填滿(mǎn)