当前位置:嗨网首页>书籍在线阅读

24-通道基础

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

12.6.1 通道基础

通道(Channel)从概念上来讲,非常类似于Java的阻塞队列(BlockingQueue)。BlockingQueue位于Java的Concurrent中,使用它可以有效地解决多线程中要求的高效安全的数据传输问题。BlockingQueue有两个常用的方法。

  • take():取走BlockingQueue中排在首位的对象,如果BlockingQueue为空,则阻塞队列进入等待状态,直到BlockingQueue中有新的数据加入。
  • put(E e):将对象e添加到BlockingQueue中,如果BlockQueue没有空间,则调用该方法的线程会被阻塞,直到BlockingQueue里面有空间再继续。

二者的关键区别在于,通道支持挂起操作,而不是被阻塞,同时通道还可以被关闭。代码如下。

fun main(args: Array<String>) = runBlocking {
    val channel = Channel<Int>()
    launch {
        // 模拟CPU耗时计算或异步逻辑处理
        for (x in 1..5) channel.send(x * x)
    }
    // 打印5个接收到的整数
    repeat(5) { println(channel.receive()) }
    println("Done!")
}

运行上面的代码,输出的结果如下。

1
4
9
16
25
Done!

在上面的实例中,Channel调用的是会合通道RendezvousChannel()。会合通道中没有任何缓冲区,调用send函数时通道被挂起,直到另一个协程调用receive函数,然后receive函数挂起,直到另一个协程调用send函数,这是一个完全无锁的实现。