浅谈Android生产者消费者模式

感觉时间好快,眨眼就到周三了。今天推送一篇 Nipuream 的实战投稿,主要通过异步加载图片来阐述生产者消费者模式。虽然性能不及Picasso或Glide等图片加载库,但是实现的思路是值得分享的。


另外今天的代码采用图片的形式(主要是由于实战类文章代码较多,文本模式换行后阅读不便),感兴趣的朋友只能亲自敲一敲了。


Nipuream 的博客地址:http://blog.csdn.net/yanghuinipurean




概述


话说生产者-消费者模型可是并发模型中的一个经典案例了,你可能会问,这种并发情况,一般服务端程序用的比较多吧,Android端的应用程序哪有什么并发情况。虽然事实如此,但是构建生产者-消费者模型,是线程间协作的思想,工作线程的协助是为了让UI线程更好地完成工作,提高用户体验。比如,下面的一种情况:



这是我们开发中很常见的一种情景,访问大量图片资源。因为图片访问是一个网络耗时任务,如果完全交由UI线程去处理,显然用户体验不佳,只能在适配器(Adapter)中的getView()方法做网络异步请求。很多人都通过第三方框架来实现异步的效果,虽然图片加载的处理要比我们好很多,但是用户体验的效果还是不佳。在比如说像图片的那样,如何做到异步加载,这都是由工作线程协助UI线程去完成的,使用生产者-消费者模型则有助于提高的用户体验。

    

生产者-消费者模型的构造


在这里,可以提前准备一个队列或者集合,作为缓冲区,把用户拖动操作作为生产者,因为用户一拖动就会调度getView()方法,那么我们在getView()方法中就向缓冲区存放网络请求任务。那么,消费者就是我们的工作线程,我们在工作线程将任务取出,并且加载到内存中,由Hander来切换到UI线程中,完成更新。更为主要的是,如何将任务放入队列中或者什么时间取出任务;从队列中取出哪个任务;什么时候执行任务;怎样执行任务......这个决策权完全由我们掌握,这样,我们就把UI线程的压力给释放出来了。


实现滚动监听


这里用Vector来实现队列的效果,当然也可以选择其它方式。


实现GridView/ListView的滚动监听:


这样我们就知道,用户使用的状态了。


消费者


我们要在Adapter中启动一条工作线程,充当消费者:



生产者


在Adapter的getView()方法,放入任务,生产者所做的事情:



UI操作以及缓存


在Handler中,将任务交给Volley处理,并且更新UI:



在此之前,指定一层硬缓存(不一定要加,可以选择加上)。选择继承的是LinkedHashMap,内部采用了LRU算法,即不常用的实体,最先被清理:



到此我们的生产者-消费者模型已经构建完了,这样一来,用户体验就会提升一个档次,不相信的可以下载代码,运行下,哈哈。


其它队列方式


当然,如果你觉得代码繁琐,还有种更为简单的方式,我们可以采用java并发库里面的工具ConcurrentLinkedQueue来充当我们的队列,当然这个队列就是真的队列,采用的是先进先出的行为,我们就不能对任务的取出的顺序进行操作了,也就达不到倒序加载或者随机加载了的效果了。但是代码非常的简洁。


ConcurrentLinkedQueue队列的特点就是内部采用了CAS原子操作,是一种非阻塞的同步队列,所以就没必要我们对其加锁了。




如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。


欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值