Kotlin Channel學(xué)習(xí)

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)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,071評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,409評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,569評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,360評(píng)論 6 404
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,895評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,123評(píng)論 0 286
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,643評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,559評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,742評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評(píng)論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,981評(píng)論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,363評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,622評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,354評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,707評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容