19 | Channel:为什么说Channel是“热”的?
Channel 就是管道
- 深入了解
- 翻译
- 解释
- 总结
Kotlin协程中的Channel技术是一项重要的并发处理工具,用于解决协程需要返回多个结果的场景。相比传统的挂起函数和async,Channel可以实现实时更新的消息接收和数据传输,大大简化了复杂度。本文深入探讨了Channel的应用场景、与其他并发手段的比较,以及其“热”特性。通过学习Channel,读者可以更好地理解Kotlin协程的特性和应用,为解决实际业务问题提供了新的思路和工具。 文章首先介绍了Channel的基本概念和创建方式,强调了其在传递多个数据组成的流时的重要性。同时,文章还探讨了Channel的“热”特性,指出无论是否有接收方,Channel的发送方都会主动工作,为数据流传递提供了便利。此外,文章还分析了Channel的源码定义,指出其能力是来自于SendChannel、ReceiveChannel这两个接口的组合,为读者提供了对Channel设计的更深入理解。 总的来说,本文通过深入讨论Channel的特性和使用方式,为读者提供了对Kotlin协程中Channel技术的全面了解,为他们在实际业务中应用Kotlin协程提供了有益的指导和建议。通过本文的阅读,读者可以快速了解Channel技术的重要性和应用价值,为其在并发处理中的实际应用提供了有力支持。
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
全部留言(21)
- 最新
- 精选
- AllenChannel 是“热”的可能会导致一下几个问题: 1. 可能会导致数据的丢失。 2. 浪费不必要的程序资源,类似于非懒加载的情况。 3. 如果未及时 close 的话,可能会导致内存泄露。
作者回复: 总结到位~
2022-03-0214 - jimChannel平时工作中有 哪些使用场景???
作者回复: 常规业务开发其实很少会需要用到Channel,Channel的使用场景其实是比较偏底层的,比如说我在课程开头提到的IM消息通道、股票行情实时刷新,等等。
2022-03-314 - 神佑小鹿1、最开始 channel.receive () 先调用,但是 channel 没有 item,所以挂起; 2、协程启动要时间,send(it) 后调用,发送 item,然后 输入 “send1”; 3、 协程循环再调用 send(it),此时队列已经满了,所以挂起,并唤起接收协程,然后 输入 “receive1”; 3、接收协程... ... ...
作者回复: 是的。
2022-04-103 - Geek_8a5ee1可以讲一下viewModelScope的区别吗
作者回复: viewModelScope是Android当中的内容,三言两语讲不清,我会尝试在Android篇里加入一些内容,请留意之后的第34讲的内容。
2022-03-073 - êwěnRecieve的cancel是清空channel中的消息,但不会close吧? 像go中如果在consumer 中关闭,会导致sender的panic。感觉kotlin也有这种陷阱。
作者回复: 在Kotlin当中,我们调用cancel()以后,管道中的消息会被清空,同时,管道也会标记为cancel,这时候,我们已经可以认为它是关闭状态了。上游如果继续发送的话,会产生异常。具体可以看看下面这个代码: ``` fun main() = runBlocking { // 无限容量的管道 val channel = Channel<Int>(Channel.UNLIMITED) { println("onUndeliveredElement = $it") } // 等价这种写法 // val channel = Channel<Int>(Channel.UNLIMITED, onUndeliveredElement = { println("onUndeliveredElement = $it") }) // 放入三个数据 (1..3).forEach { channel.send(it) } // 取出一个,剩下两个 channel.receive() // 取消当前channel println(channel.isClosedForReceive) println(channel.isClosedForSend) channel.cancel() println(channel.isClosedForReceive) println(channel.isClosedForSend) channel.send(4) } ```
2022-03-0223 - Paul Shan对于接收方而言,热的Channel状态是时刻改变的,数据之间是强依赖。简单的情况还好,如果Channel的数据级联了几次之后,调试就成了噩梦,这和滥用EventBus一样。
作者回复: 没错,所以多个Channel组合的情况,我们需要三思而后行。
2022-03-242 - 白乾涛以上代码看起来是可以正常工作了。但是,我仍然不建议你用这种方式。因为,当你为管道指定了 capacity 以后,以上的判断方式将会变得不可靠!原因是目前的 1.6.10 版本的协程库,运行这样的代码会崩溃,如下所示: ------------- 这是现象,而不是原因呀,具体原因是什么呢?
作者回复: 原因就是:到目前为止isClosedForReceive是ExperimentalCoroutinesApi,它的功能仍然是有缺陷的。当Channel有capacity 以后,Kotlin官方支持的并不好,所以我们暂时不应该用它。
2022-03-122 - 魏全运为什么例子中是ReceiveChannel 在send?
作者回复: 你说的produce{}吗?在它的Lambda当中,我们是可以调用send()方法的,而它的返回值是ReceiveChannel。这不是一个概念哈。
2022-03-0821 - Xs.Ten老师好,请问Channel 里面 Sender 和 Receiver 的身份可以发生互换么?
作者回复: Channel的接口本身是通过组合得来的,理论上我们是可以让它们互换的,但不建议这么干。
2022-03-26 - 梁中华public fun <E> Channel( capacity: Int = RENDEZVOUS, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, onUndeliveredElement: ((E) -> Unit)? = null ): Channel<E> Channel居然也是个方法,为啥方法名是大写字母开头的? 难道是因为它是顶层方法?
作者回复: 这是Kotlin 命名的一种特色。
2022-03-213