当Httpclient遇到线程池(记一次爬虫经历)

来源:互联网 发布:mac如何下载b站视频 编辑:程序博客网 时间:2024/06/15 01:53

要抓的数据量有点多,很多个页面,并且都一样的处理,那么直接就上线程池吧.搜了搜,得到了结果,用Executors.newFixedThreadPool()来生产出一个固定大小的线程池,后面所有的任务都会被放置在任务队列中.ok,开始写

java线程池的使用

建立线程池

ExecutorService executorService = Executors.newFixedThreadPool(10);
这就建立了一个大小为10的线程池

提交任务

executorService.submit(Runnable task);

等待所有任务都完成再继续执行下面的代码

executorService.shutdown();//不在接受新任务while (true) {    if (executorService.isTerminated()) {        break;//所有任务完成后跳出这个检测循环    }    Thread.sleep(1000);}

和Httpclient有什么关系呢?

这是我提交任务的代码

//Crawl是我实现Runnable接口的类
executorService.submit(new Crawl(client));//把外部的client实例传进去

在于提交任务这一条代码,我的task最开始需要外部提供一个HttpClient实例,我的实现是在外部只生成一个HttpClient实例,每次启动新任务都把这个client传进去(心想着这样可以省去在每个线程中生成新client的过程,应该可以提高效率)
但是事实是用上面的方法真的是特别特别的慢,虽然可能是比单线程快,但是还是慢的让人着急,并且在抓一些数据后会频繁发生各种”超时异常”,直到我灵光一现,想着让每个线程自己去new自己的HttpClient对象吧,不管它了,试一试,一下子,我感觉自己在天上飞,真的,飞起来了,快的我想哭.真的

重要的事说三遍
请在每个线程中生成自己的HttpClient实例
请在每个线程中生成自己的HttpClient实例
请在每个线程中生成自己的HttpClient实例

1 1