这段时间对网络爬虫比较感兴趣,实现起来实际上比较简单。无非就是http的web请求,然后对返回的html内容进行内容筛选。本文的重点不在于这里,而在于多线程做http请求。例如我要实现如下场景:我有N个对象集合,需要通过http的方式获取每个对象的相关信息。废话不多说,直接上代码

实现方式一:依次循环遍历对象集合,这种方式最为普通

for (int i = ; i < videoInfoList.Count; i++)
{
//普通方式
directRun(videoInfoList[i]);
} private void directRun(VideoInfo item)
{
var htmlStr = GetHtmlCode(item.url);
item.name= getName(htmlStr);
videoInfoQueue.Enqueue(item);
} private static string GetHtmlCode(string url)
{
string htmlCode;
HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
webRequest.Timeout = ;
webRequest.Method = "GET";
webRequest.UserAgent = "Mozilla/4.0";
webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
try
{
HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse();
using (System.IO.Stream streamReceive = webResponse.GetResponseStream())
{
using (var zipStream = new System.IO.Compression.GZipStream(streamReceive, System.IO.Compression.CompressionMode.Decompress))
{
using (StreamReader sr = new System.IO.StreamReader(zipStream, Encoding.UTF8))
{
htmlCode = sr.ReadToEnd();
}
}
}
}
catch
{
return null;
}
finally
{
// 释放资源
webRequest.Abort();
}
return htmlCode;
}

实现方式二:使用线程池,使用异步多线程的方式提高效率

在使用线程池的时候一定要注意设置ServicePointManager.DefaultConnectionLimit, 因为默认不设置是2,会导致同时的http请求只能是2个,因为这个问题我自己也卡了很久。使用队列管理,启动一个定时器线程,实时刷新显示获取到的数 据。实际的开发中,队列和线程池往往是一对组合出现。至于入队时候使用锁的问题,这里可以使用volatile也可以直接使用object锁,防止入队出错

//已经入队的数目
private int loadingNum = ;
//总数目
private int importNum = ;
//定义队列
private Queue<VideoInfo> videoInfoQueue = new Queue<VideoInfo>();
//锁
private object sb = new object(); ServicePointManager.DefaultConnectionLimit = ;
for (int i = ; i < videoInfoList.Count; i++)
{
//多线程
ThreadPool.QueueUserWorkItem(multithreadingRun, videoInfoList[i]);
Thread.Sleep();
} private void multithreadingRun(object o)
{
VideoInfo item = o as VideoInfo;
var htmlStr = GetHtmlCode(item.url);
item.name = getName(htmlStr);
//使用锁入队
lock (sb)
{
videoInfoQueue.Enqueue(item);
}
} //使用定时器进行出队显示
private void Timer1_Tick(object sender, EventArgs e)
{
if (videoInfoQueue.Count > )
{
VideoInfo item = videoInfoQueue.Dequeue();
label1.Text ++= item.name;
}
if (loadingNum == importNum)
{
timer1.Stop();
}
}

至此,结束,本文也是我的第一篇博文,欢迎指教!

如何在http请求中使用线程池(干货)的更多相关文章

  1. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

  2. Java5中的线程池实例讲解

    Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活.本文通过一个网络服务器模型,来实践Java5的多线程 ...

  3. 探究ElasticSearch中的线程池实现

    探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...

  4. Spring中的线程池ThreadPoolTaskExecutor介绍

    前言: Java SE 5.0引入了ThreadPoolExecutor.ScheduledThreadPoolExecutor.Spring 2.x借助ConcurrentTaskExecutor和 ...

  5. C#中的线程池使用(一)

    1  线程池的概念 许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化 ...

  6. mina2中的线程池

    一.Mina中的线程池模型 前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在.Mina的线程调度原理主要如下图所示: A ...

  7. 【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

    碎碎念 关于JDK源码相关的文章这已经是第四篇了,原创不易,粉丝从几十人到昨天的666人,真的很感谢之前帮我转发文章的一些朋友们. 从16年开始写技术文章,到现在博客园已经发表了222篇文章,大多数都 ...

  8. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  9. 【并发编程】线程池是否需要手动关闭吗?以Hutool中的线程池为例

    Hutool工具包中使用线程池的API是: ThreadUtil.execute() /** * 直接在公共线程池中执行线程 * * @param runnable 可运行对象 */ public s ...

随机推荐

  1. 双刃剑MongoDB的学习和避坑

    双刃剑MongoDB的学习和避坑 MongoDB 是一把双刃剑,它对数据结构的要求并不高.数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档.所以我们在使用的过程中非常方 ...

  2. spring的PathVariable和value={}小技巧(shiro项目中来的三)

    <property name="successUrl" value="/main/index" /> @RequestMapping(value=& ...

  3. activemq的案例

  4. HALCON学习-下载、安装

    下载地址: 官网 HALCON学习网 安装: 直接安装文件halcon-12.0-windows-x86.exe 破解,汉化: 在HALCON学习网中有Licence文件“license_suppor ...

  5. GridView中使用 jQuery DatePicker (UpdatePanel)

    1.无UpdatePanel   1.代码 <script> $(function () { $('.myDatePickerClass').datepicker({ dateFormat ...

  6. HiHocoder1415 : 后缀数组三·重复旋律3 & Poj2774:Long Long Message

    题面 HiHocoder1415 Poj2774 Sol 都是求最长公共子串,\(hihocoder\)上讲的很清楚 把两个串拼在一起,中间用一个特殊字符隔开 那么答案就是排序后相邻两个不同串的后缀的 ...

  7. [BZOJ1045] [HAOI2008] 糖果传递 (贪心)

    Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=,表示小朋友的个数.接下来n行,每行 ...

  8. 两种插入排序算法java实现

    两种方法都编译运行通过,可以当做排序类直接使用. 折半插入排序: public class Sort1 { public static void main(String[] args) { Inser ...

  9. handsontable自定义渲染

    本文主要介绍在使用Handsontable过程中,对加载的数据进行字体颜色.样式(style).数据格式化,对齐方式的处理,并添加自定义图片和单机事件功能. 代码如下: <!DOCTYPE ht ...

  10. c# 使用EnyimMemcached 连接memcache

    首先nuget安装EnyimMemcached,本地启动memcache,往app.config(mvc项目则是web.config)加入以下内容: configSection内加入: <sec ...