简述
在java中通常用LinkedBlockingQueue去实现一个阻塞队列,目的是实现生产者与消费者模型,该模型是一个多线程同步问题的经典案例,生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
在kotlin中同样也有该实现,是通过协程Channel实现的,当你异步操作的时候可以通过channel传递消息。有一点需要知道,Channel的缓冲去可以是0个,当有信息send进去后,协程就会被挂起,只有被调receive后才会继续执行。
Channel实现的阻塞队列并不是真正的阻塞,而是协程被挂起,所以这点还是比LinkedBlockingQueue实现的队列要更轻量级。
Demo
下面举个官方栗子:
在协程runBlocking中,实例化channel对象,泛型是Int代表要传递Int类型的值,在异步协程launch中循环发送,在接下来的执行中repeat 5次打印接受的消息。
这里可以看出channel有个特点:
它可以在不同协程中随意传递消息,而且是安全的。
打印结果:
再举个官方栗子:
channel还有个特点是阻塞队列没有,它可以随时关闭,当发送者接收到关闭指令,将立即停止发送。
是不是这样就没了,每次都要自己new一个channel,还要for循环去接收,有点接受不了吧。官方封装了更加简单的用法,通过produce实现,并在接收方通过consumeEach代替for循环
再++举个栗子:
produce在工作线程中send数据,squares通过consumeEach接收。是不是简单多了。
总结
协程总是以更轻量级,更安全,更高效的方式去解决并发中的问题,这点很赞,而且我们相信kotlin在不久的将来会是一门很热门的语言。愿在android的道路上与你携手到老,情人节快乐。