延迟值提供了一种在协程之间传输单个值的便捷方法。通道提供了一种传输值流的方法。实现不同协程之间的通信,Channel本质是一个并发安全的队列,Channel是热数据流

image.png

  • channel既然是队列就有容量,默认是0
  • channel容量满了之后,不消费send就会被挂起
  • 发送元素只能被消费一次
  1. val channel = Channel<Int>()
  2. launch {
  3. // 消耗大量cpu计算
  4. for (x in 1..5) channel.send(x * x)
  5. }
  6. // here we print five received integers:
  7. repeat(5) { println(channel.receive()) }
  8. println("Done!")

生产者channel便捷方法

fun channel_1() = runBlocking<Unit> {
    //生产channel  produce快速生产channel协程
    val produce: ReceiveChannel<Int> = GlobalScope.produce {
        repeat(100) {
            send(it)
        }
    }

    //消费 一个元素只能消费一次
    val consumer = GlobalScope.launch {
        for (i in produce) {
            println("consumer0:${i}")
        }
    }
     val consumer2 =GlobalScope.launch {
         for (i in produce){
             println("consumer2:${i}")
         }
     }
    val consumer3 =GlobalScope.launch {
        for (i in produce){
            println("consumer3:${i}")
        }
    }
    consumer.join()
    consumer2.join()
    consumer3.join()
}

消费者channel便捷方式

Channel的关闭

image.png

BroadcastChannel

一对多,一个元素可以被多个消费者消费,只要订阅了就可以

image.png

fun channel_broadcast() = runBlocking {
    val broadcastChannel = BroadcastChannel<Int>(10)
    val produce = GlobalScope.launch {
        List(2) {
            delay(100)
            broadcastChannel.send(it)
            println("广播 :$it")
        }
        broadcastChannel.close()
        println(" ${broadcastChannel.isClosedForSend}")
    }
    List(2) { index ->
        GlobalScope.launch {
            val openSubscription = broadcastChannel.openSubscription()
            for (i in openSubscription) {
                println("$index 接收者 收到内容:$i")
            }
        }
    }.joinAll()
}

Channel转换为BroadcastChannel

val channel = Channel<Int>()
val broadcast = channel.broadcast(Channel.BUFFERED)