美文网首页
Kotlin Channel学习

Kotlin Channel学习

作者: 飞哥278999401 | 来源:发表于2022-08-17 22:43 被阅读0次

channel用于协程之间的通讯,使用send和receive往通道里写入或者读取数据,2个方法为非阻塞挂起函数,channel是热流,不管有没有订阅者都会发送。

Channel的简单使用


       val channel = Channel<Int>()
        launch {

            channel.send(111)

        }


        launch {

            println("receive:" + channel.receive())

        }

打印 receive:111

Channel 默认是0容量的buffer

send是个挂起函数,发送到通道,如果通道buffer已满,就会挂起调用者

例如:

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) 发送到通道后,通道满了,调用者的协程被挂起,所以 println("sendafter:222")不执行了

recevie调用时,如果通道里不为空,就从通道里把元素拿出来,并且从通道里移除元素,如果通道元素为空,则挂起调用者,等通道有元素后 才会执行

例如

    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时 通道里没有元素,被挂起,5秒后发送了元素,继续执行

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完毕后,调用channel.close即可执行完毕,打印receive end

Channel的四种类型

Rendezvous channel(默认类型): 0尺寸buffer,send是个挂起函数,发送到通道,如果通道buffer已满,就会挂起调用者,这个0buffer,发送一个,如果没人接收,调用者就被挂起

Buffered channel:指定元素大小,发送当buffer满了后Send会被挂起。

Conflated channel: 新元素会覆盖旧元素,receiver只会得到最新元素,Send永不挂起。

Unlimited channel: buffer无限,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 发送了1后,接受了1,继续发送2,因为buffer是0,所以满了,2没人接收,所以调用者被挂起,没有打印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) 发送了1后,接受了1,继续发送2 3 4,因为buffer是2,发送了2和3后,所以满了,2没人接收,所以调用者被挂起,没有打印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 只会接收最新值  但是在2次send之间delay1毫秒,会取第一次的,应该机制是send被挂起之前的最新值,挂起后 就算另外一批次的发送了

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 只会接收最新值 receive 1-2 receive end, send方法不会挂起,因为buffer无限大,不会被填满

相关文章

  • Kotlin Channel学习

    channel用于协程之间的通讯,使用send和receive往通道里写入或者读取数据,2个方法为非阻塞挂起函数,...

  • # kotlin channel 入门

    kotlin channel 入门 前言 最近项目中对 kotlin 的使用比较多。不得不说 kotlin 确实...

  • kotlin中channel

    channel用于协程之间的通讯,使用send和receive往通道里写入或者读取数据,2个方法为非阻塞挂起函数,...

  • Kotlin语言(十二):Channel

    注:本文中使用 runBlocking 是为了方便测试,业务开发中禁止使用 一、Channel 基础 (1)Cha...

  • Kotlin学习之Kotlin初识

    Kotlin学习之Kotlin初识 @(Kotlin学习) 一、什么是Kotlin? Kotlin,是JetBra...

  • Kotlin学习笔记:类和接口

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:概述

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin 学习笔记:基本语法和函数

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:注解和反射

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:泛型

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

网友评论

      本文标题:Kotlin Channel学习

      本文链接:https://www.haomeiwen.com/subject/jqvdgrtx.html