<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Kotlin協程中的Channel用於處理多個資料組合的流,隨用隨取,時刻準備著,就像自來水一樣,開啟開關就有水了。
fun main() = runBlocking { logX("開始") val channel = Channel<Int> { } launch { (1..3).forEach{ channel.send(it) logX("傳送資料: $it") } // 關閉channel, 節省資源 channel.close() } launch { for (i in channel){ logX("接收資料: $i") } } logX("結束") }
範例程式碼 使用Channel建立了一組int型別的資料流,通過send傳送資料,並通過for迴圈取出channel中的資料,最後channel是一種協程資源,使用結束後應該及時呼叫close方法關閉,以免浪費不必要的資源。
public fun <E> Channel( capacity: Int = RENDEZVOUS, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, onUndeliveredElement: ((E) -> Unit)? = null ): Channel<E> = when (capacity) { RENDEZVOUS -> {} CONFLATED -> {} UNLIMITED -> {} else -> {} }
可以看到Channel的建構函式包含了三個引數,分別是capacity、onBufferOverflow、onUndeliveredElement.
首先看capacity,這個引數代表了管道的容量,預設引數是RENDEZVOUS,取值是0,還有其他一些值:
接下來看onBufferOverflow, 顧名思義就是管道容量滿了,怎麼辦?預設是掛起,也就是suspend,一共有三種分別是:
SUSPNED、DROP_OLDEST以及DROP_LATEST
public enum class BufferOverflow { /** * Suspend on buffer overflow. */ SUSPEND, /** * Drop **the oldest** value in the buffer on overflow, add the new value to the buffer, do not suspend. */ DROP_OLDEST, /** * Drop **the latest** value that is being added to the buffer right now on buffer overflow * (so that buffer contents stay the same), do not suspend. */ DROP_LATEST }
最後一個引數是onUndeliveredElement,從名字看像是沒有投遞成功的回撥,也確實如此,當管道中某些資料沒有成功接收時,這個就會被呼叫。
綜合這個引數使用一下
fun main() = runBlocking { println("開始") val channel = Channel<Int>(capacity = 2, onBufferOverflow = BufferOverflow.DROP_OLDEST) { println("onUndeliveredElement = $it") } launch { (1..3).forEach{ channel.send(it) println("傳送資料: $it") } // 關閉channel, 節省資源 channel.close() } launch { for (i in channel){ println("接收資料: $i") } } println("結束") }
輸出結果如下:
開始
結束
傳送資料: 1
傳送資料: 2
傳送資料: 3
接收資料: 2
接收資料: 3
先看一個例子
val channel: ReceiveChannel<Int> = produce { (1..100).forEach{ send(it) println("傳送: $it") } } while (!channel.isClosedForReceive){ val i = channel.receive(); println("接收: $i") }
輸出報錯資訊:
Exception in thread "main" kotlinx.coroutines.channels.ClosedReceiveChannelException: Channel was closed
可以看到使用isClosedForReceive判斷是否關閉再使用receive方法接收資料,依然會報錯,所以不推薦使用這種方式。
推薦使用上面for迴圈的方式取資料,還有kotlin推薦的consumeEach方式,看一下範例程式碼
val channel: ReceiveChannel<Int> = produce { (1..100).forEach{ send(it) println("傳送: $it") } } channel.consumeEach { println("接收:$it") }
所以,當我們想要獲取Channel當中的資料時,我們儘量使用 for 迴圈,或者是channel.consumeEach {},不要直接呼叫channel.receive()。
先看一下程式碼
println("開始") val channel = Channel<Int>(capacity = 3, onBufferOverflow = BufferOverflow.DROP_OLDEST) { println("onUndeliveredElement = $it") } launch { (1..3).forEach{ channel.send(it) println("傳送資料: $it") } } println("結束") }
輸出:
開始
結束
傳送資料: 1
傳送資料: 2
傳送資料: 3
可以看到上述程式碼中並沒有 取channel中的資料,但是傳送的程式碼正常執行了,這種“不管有沒有接收方,傳送方都會工作”的模式,就是我們將其認定為“熱”的原因。
舉個例子,就像去海底撈吃火鍋一樣,你不需要主動要求服務員加水,服務員看到你的杯子中水少了,會自動給你新增,你只管拿起水杯喝水就行了。
總的來說,不管接收方是否存在,Channel 的傳送方一定會工作。
通過原始碼可以看到Channel只是一個介面,它的能力來源於SendChannel和ReceiveChannel,一個傳送管道,一個接收管道,相當於做了一個組合。
這也是一種良好的設計思想,“對讀取開放,對寫入封閉”的開閉原則。
到此這篇關於Kotlin Channel處理多個資料組合的流的文章就介紹到這了,更多相關Kotlin Channel內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45