前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Kotlin 协程】Channel 通道 ④ ( Channel 通道的热数据流属性 | Channel 通道关闭过程 | Channel 通道关闭代码示例 )

【Kotlin 协程】Channel 通道 ④ ( Channel 通道的热数据流属性 | Channel 通道关闭过程 | Channel 通道关闭代码示例 )

作者头像
韩曙亮
发布2023-03-30 18:32:59
4920
发布2023-03-30 18:32:59
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、Channel 通道的热数据流属性


调用 CoroutineScope#produce 函数 构造的 生产者协程 , 以及 调用 CoroutineScope#actor 函数 构造的 消费者协程 ,

如果上述 生产者协程 和 消费者协程 执行完毕 , 则 对应的 Channel 通道 也会进行关闭 ,

因此 , Channel 通道 被称为 热数据流 ;

与 Channel 通道 热数据流 相对的是 Flow 异步流 的冷数据流 特征 ;

二、Channel 通道关闭过程


如果调用 Channel 通道的 Channel#close 函数 , 该 Channel 通道会 停止接收 新的数据 ,

此时调用 Channel#isClosedForSend 函数 , 会返回 true ;

Channel 通道存在缓冲区 , 通道不接收新的元素 , 但是 缓冲区已存储的元素需要被处理完毕 , 然后才能关闭通道 ,

当 Channel 通道 缓冲区 所有的元素处理完毕 , 调用 Channel#isClosedForReceive 函数 会返回 true ;

三、Channel 通道关闭代码示例


在下面的代码中 , Channel 通道缓冲区大小为 3 , 数据生产者 一次性将 3 个数据全部发送出去 , 但是 数据消费者 每秒只能消费一个数据 , 需要 3 秒才能将数据处理完毕 ;

在发送完数据后 , 调用 Channel#close 函数 , 关闭通道 , 此时 channel.isClosedForSend 为 true , 但是 channel.isClosedForReceive 为 false ;

在接收数据完毕后 , channel.isClosedForReceive 才变为 true , Channel 通道正式关闭 ;

代码示例 :

代码语言:javascript
复制
package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking {
            // Channel 通道, 传递 Int 类型数据
            val channel = Channel<Int>(3)

            // 数据生产者协程
            val producer = GlobalScope.launch {
                for (i in 0..2) {
                    channel.send(i)
                    println("向通道中发送数据 $i, channel.isClosedForSend : ${channel.isClosedForSend}, channel.isClosedForReceive : ${channel.isClosedForReceive}")
                }
                // 关闭通道
                channel.close()
                println("数据发送完毕, channel.isClosedForSend : ${channel.isClosedForSend}, channel.isClosedForReceive : ${channel.isClosedForReceive}")
            }

            // 数据消费者协程
            val consumer = GlobalScope.launch {
                for(num in channel) {
                    delay(1000)
                    println("从通道中接收数据 $num, channel.isClosedForSend : ${channel.isClosedForSend}, channel.isClosedForReceive : ${channel.isClosedForReceive}")
                }
                println("数据接收完毕, channel.isClosedForSend : ${channel.isClosedForSend}, channel.isClosedForReceive : ${channel.isClosedForReceive}")

            }

            // 等待两个协程执行完毕
            joinAll(producer, consumer)
        }
    }
}

执行结果 :

代码语言:javascript
复制
2022-12-28 11:07:06.509 I/System.out: 向通道中发送数据 0, channel.isClosedForSend : false, channel.isClosedForReceive : false
2022-12-28 11:07:06.509 I/System.out: 向通道中发送数据 1, channel.isClosedForSend : false, channel.isClosedForReceive : false
2022-12-28 11:07:06.509 I/System.out: 向通道中发送数据 2, channel.isClosedForSend : false, channel.isClosedForReceive : false
2022-12-28 11:07:06.510 I/System.out: 数据发送完毕, channel.isClosedForSend : true, channel.isClosedForReceive : false
2022-12-28 11:07:07.516 I/System.out: 从通道中接收数据 0, channel.isClosedForSend : true, channel.isClosedForReceive : false
2022-12-28 11:07:08.527 I/System.out: 从通道中接收数据 1, channel.isClosedForSend : true, channel.isClosedForReceive : false
2022-12-28 11:07:09.540 I/System.out: 从通道中接收数据 2, channel.isClosedForSend : true, channel.isClosedForReceive : true
2022-12-28 11:07:09.540 I/System.out: 数据接收完毕, channel.isClosedForSend : true, channel.isClosedForReceive : true
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、Channel 通道的热数据流属性
  • 二、Channel 通道关闭过程
  • 三、Channel 通道关闭代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档