Kotlin协程 - - - Channel

一.Channel

 Channel实际上是一个并发安全的队列,它可以用来连接协程,实现不同协程的通信。

1.Channel的使用

导入依赖

 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'

   在不同协程,用Channel来实现发送与接收。

//Channel的发送与接收
fun testKnowChannel()= runBlocking {
    val channel = Channel<Int> ()
    //发送者
    val launch = GlobalScope.launch {
        while (true) {
            var i = 0
            delay(1000)
            //发送
            channel.send(++i)
            println("send $i")
        }
    }
    //接收者 
    val launch1 = GlobalScope.launch {
        while (true) {
            val element = channel.receive()
            println("receive $element")
        }
    }
    joinAll(launch,launch1)
}

结果演示:

2.Channel缓冲

Channel实际上就是一个队列,队列中一定存在缓冲区,那么一旦这个缓冲区满了,并且也一直没有人调用receive并取走函数,send就需要挂起。故意让接收端的节奏放慢,发现send总是会挂起,直到receive之后才会继续往下执行。

//Channel的发送与接收
fun testKnowChannel()= runBlocking {
    val channel = Channel<Int> ()
    //发送者
    val launch = GlobalScope.launch {
        while (true) {
            var i = 0
            delay(1000)
            channel.send(++i)
            println("send $i")
        }
    }
    //接收者  顺序不会变
    val launch1 = GlobalScope.launch {
        while (true) {
            delay(2000)
            val element = channel.receive()
            println("receive $element")
        }
    }
    joinAll(launch,launch1)
}

结果演示:


 

 我在接收的是延时2秒,比发送的延时长,但并没又造成一次接送多次数据的Channel是有缓冲的

3.迭代Channel

Channel体身确实像序列,所以我们在读取的时候可以直接获取一个Channel的iterator。
 

//Channel的迭代器
fun testIterateChannel()= runBlocking {
                                             //缓冲大小
    val channel = Channel<Int> (Channel.UNLIMITED)
    //发送者
    val launch = GlobalScope.launch {
            for (x in 1..5){
                channel.send(x*x)
                println("send: ${x * x}")
            }
    }
    //接收者
    val launch1 = GlobalScope.launch {
       /*     val iterator = channel.iterator()//迭代器
        while (iterator.hasNext()){
            val next = iterator.next()//
            println("receive $next")
            delay(2000)
        }*/
        //这是for循环写法
        for (element in channel){
            println("receive $element")
            delay(2000)
        }
    }
    joinAll(launch,launch1)
}

结果演示。

4.produce与actor

1. 构造生产者与消费者的便捷方法。
2. 我们可以通过p℃duce方法启动一个生产者协程,并返回一个ReceiveChanneI,其他协程就可以用这个Channe|来接收数据了。反过来,我们可以用actor启动一个消费者协程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值