一直听说生产消费者模式,当然,仅仅只是听说。因为一直很少接触线程并发开发,以为这东西自己会很少接触,知道看到了阿里巴巴的方腾飞这篇文章才焕然大悟:并非没有应用的场景,只是自己没有这种意识去采取这样的设计理念。
##16.1 视频采集需求
之前做过一个视频资源采集系统,需求如下:
- 视频来源于不同的网站;
- 接口可以指定获取的数据页数以及数据大小,例如video?pageNo=10&pageSize=100;
- 每个网站的接口和数据格式都不相同,插入数据库前需要对数据格式进行转换;
##16.2 做法一:单线程串行处理
// FIXME
public void getAndSaveVideo(itn pageNo, int pageSize) {
List<Video> videos = exactVideos(pageNo, pageSize); // 获取前10页,每页100条数据
db.save(videos); // 插入到数据库中
}
private List<Video> exactVideos(int pageNo, int pageSize) {
List<Video> videos = new ArrayList<Video>();
for(int i=0; i < pageNo; pageSize) {
List<Video> pageVidoes = getVideoByUrl("http://www.youku.com?pageNo="+i+"&pageSize=" + pageSize);
videos.add(pageVidoes);
}
}缺点:
- 接口数据采集过程中,网络传输浪费大量时间,db.save()always waiting。
- 采集任务由于网络不稳定容易被挂起,导致后面的任务无法继续执行,前功尽弃
##16.3 单线程耦合处理
private List<Video> exactVideos(int pageNo, int pageSize) {
for(int i=0; i < pageNo; pageSize) {
List<Video> pageVidoes = getVideoByUrl("http://www.youku.com?pageNo="+i+"&pageSize=" + pageSize);
db.save(pageVidoes);
}
}缺点:
- 采集任务和保存数据耦合过高,当多个网站采集处理时都需要如是写;
- db.save()必须等待每次采集后才能插入数据,效率不高;
##16.4 生产者消费者模式
##16.5 优势