轻松把玩HttpClient之封装HttpClient工具类(四),单线程调用及多线程批量调用测试

       本文主要来分享一下该工具类的测试结果。工具类的整体源码不再单独分享,源码基本上都已经在文章中了。开始我们的测试。

       单线程调用测试:

	public static void testOne() throws HttpProcessException{

		System.out.println("--------简单方式调用(默认post)--------");
		String url = "http://tool.oschina.net/";
		//简单调用
		String resp = HttpClientUtil.send(url);
		System.out.println("请求结果内容长度:"+ resp.length());

		System.out.println("\n#################################\n");

		System.out.println("--------加入header设置--------");
		url="http://blog.csdn.net/xiaoxian8023";
		//设置header信息
		Header[] headers=HttpHeader.custom().userAgent("Mozilla/5.0").build();
		//执行请求
		resp = HttpClientUtil.send(url, headers);
		System.out.println("请求结果内容长度:"+ resp.length());

		System.out.println("\n#################################\n");

		System.out.println("--------代理设置(绕过证书验证)-------");
		url="https://www.facebook.com/";
		HttpClient client= HCB.custom().timeout(10000).proxy("127.0.0.1", 8087).ssl().build();//采用默认方式(绕过证书验证)
		//执行请求
		resp = HttpClientUtil.send(client,url);
		System.out.println("请求结果内容长度:"+ resp.length());

		System.out.println("\n#################################\n");

		System.out.println("--------代理设置(自签名证书验证)+header+get方式-------");
		url = "https://sso.tgb.com:8443/cas/login";
		client= HCB.custom().timeout(10000).ssl("D:\\keys\\wsriakey","tomcat").build();
		headers=HttpHeader.custom().keepAlive("false").connection("close").contentType(Headers.APP_FORM_URLENCODED).build();
		//执行请求
		resp = HttpClientUtil.send(client, url, HttpMethods.GET, headers);
		System.out.println("请求结果内容长度:"+ resp.length());

		System.out.println("\n#################################\n");
	}

       测试结果如下:

       可以看到4次调用,都没有问题。

       那么现在试试多线程调用吧。我定义一个数组,里面有20篇文章的地址。我启动20个线程的线程池来测试,写了一个20*50次的for循环,看看全部线程结束时有没有报错,能用多长时间:

	public static void testMutilTask(){
		// URL列表数组
		String[] urls = {
				"http://blog.csdn.net/xiaoxian8023/article/details/49862725",
				"http://blog.csdn.net/xiaoxian8023/article/details/49834643",
				"http://blog.csdn.net/xiaoxian8023/article/details/49834615",
				"http://blog.csdn.net/xiaoxian8023/article/details/49834589",
				"http://blog.csdn.net/xiaoxian8023/article/details/49785417",

				"http://blog.csdn.net/xiaoxian8023/article/details/48679609",
				"http://blog.csdn.net/xiaoxian8023/article/details/48681987",
				"http://blog.csdn.net/xiaoxian8023/article/details/48710653",
				"http://blog.csdn.net/xiaoxian8023/article/details/48729479",
				"http://blog.csdn.net/xiaoxian8023/article/details/48733249",

				"http://blog.csdn.net/xiaoxian8023/article/details/48806871",
				"http://blog.csdn.net/xiaoxian8023/article/details/48826857",
				"http://blog.csdn.net/xiaoxian8023/article/details/49663643",
				"http://blog.csdn.net/xiaoxian8023/article/details/49619777",
				"http://blog.csdn.net/xiaoxian8023/article/details/47335659",

				"http://blog.csdn.net/xiaoxian8023/article/details/47301245",
				"http://blog.csdn.net/xiaoxian8023/article/details/47057573",
				"http://blog.csdn.net/xiaoxian8023/article/details/45601347",
				"http://blog.csdn.net/xiaoxian8023/article/details/45569441",
				"http://blog.csdn.net/xiaoxian8023/article/details/43312929",
				};

		// 设置header信息
		Header[] headers = HttpHeader.custom().userAgent("Mozilla/5.0").build();
		HttpClient client= HCB.custom().timeout(10000).build();

		 long start = System.currentTimeMillis();
	        try {
	            int pagecount = urls.length;
	            ExecutorService executors = Executors.newFixedThreadPool(pagecount);
	            CountDownLatch countDownLatch = new CountDownLatch(pagecount*100);
	            for(int i = 0; i< pagecount*100;i++){
	                //启动线程抓取
	                executors.execute(new GetRunnable(urls[i%pagecount], headers, countDownLatch).setClient(client));
	            }
	            countDownLatch.await();
	            executors.shutdown();
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        } finally {
	            System.out.println("线程" + Thread.currentThread().getName() + ", 所有线程已完成,开始进入下一步!");
	        }

	        long end = System.currentTimeMillis();
	        System.out.println("总耗时(毫秒): -> " + (end - start));
	        //(7715+7705+7616)/3= 23 036/3= 7 678.66---150=51.2
	        //(9564+8250+8038+7604+8401)/5=41 857/5=8 371.4--150
	        //(9803+8244+8188+8378+8188)/5=42 801/5= 8 560.2---150
	}

	 static class GetRunnable implements Runnable {
	        private CountDownLatch countDownLatch;
	        private String url;
	        private Header[] headers;
	        private HttpClient client = null;

	        public GetRunnable setClient(HttpClient client){
	        	this.client = client;
	        	return this;
	        }

	        public GetRunnable(String url, Header[] headers,CountDownLatch countDownLatch){
	        	this.url = url;
	        	this.headers = headers;
	            this.countDownLatch = countDownLatch;
	        }
	        @Override
	        public void run() {
	            try {
	            	String response = null;
	            	if(client!=null){
	            		response = HttpClientUtil.send(client, url, headers);
	            	}else{
	            		response =  HttpClientUtil.send(url, headers);
	            	}
	            	System.out.println(Thread.currentThread().getName()+"--获取内容长度:"+response.length());
	            } catch (HttpProcessException e) {
					e.printStackTrace();
				} finally {
	                countDownLatch.countDown();
	            }
	        }
	    } 

       定义了一个ExecutorService的线程池,使用CountDownLatch来保证所有线程都运行完毕,测试一下看看:

	public static void main(String[] args) throws Exception {
//		testOne();
		testMutilTask();
	}

       测试结果如下:


       从结果中可以清楚的看到执行1000次调用,总消耗是51165,平均51ms/个,速度快,而且没有报错。

       好了,本工具就分享到这里,下次会分享异步的HttpClient,敬请期待。

       代码已上传至:https://github.com/Arronlong/httpclientUtil

       httpclientUtil (QQ交流群:548452686 

时间: 2024-11-10 07:30:05

轻松把玩HttpClient之封装HttpClient工具类(四),单线程调用及多线程批量调用测试的相关文章

分页封装实用工具类及其使用方法

分页封装实用工具类及其使用方法 作者: javaboy2012 Email:yanek@163.com qq:    1046011462     package com.yanek.util; import java.util.List; public class PageBean { /** * @param args */ public static void main(String[] args) { } private int currentpage; // 当前页数 private

MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

[正文] 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据库资源中间. DAO模式实际上是两个模式的组合,即Data Accessor (数据访问者)模式和 Active Domain Object(领域对象)模式.Data Accessor 模式实现了数据访问和业务逻辑的分离:Active Domain Object 模式实现了业务数据的对象化封装. 需要注意的是,DAO设计模式是Java EE中的设计模式

MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类

[正文] 首先需要回顾一下上一篇文章中的内容:MySQL数据库学习笔记(九)----JDBC的PreparedStatement接口重构增删改查 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit.Rollback命令进行事务的提交与回滚.实际上在JDBC中也存在事务处理,如果要想进行事务处理的话,则必须按照以下的步骤完成. JDBC中事务处理的步骤: 1.要取消掉JDBC的自动提交:void setAutoCommit(b

轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)

       搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用.调用关系不清楚,结构有点混乱.所以也就萌生了自己封装HttpClient工具类的想法.要做就做最好的,本工具类支持插件式配置Header.插件式配置httpclient对象,这样就可以方便地自定义header信息.配置ssl.配置proxy等.        是不是觉得说的有点悬乎了,那就先看看调用吧: public static void testSimple() thro

轻松把玩HttpClient之封装HttpClient工具类(六),封装输入参数,简化工具类

       在写这个工具类的时候发现传入的参数太多,以至于方法泛滥,只一个send方法就有30多个,所以对工具类进行了优化,把输入参数封装在一个对象里,这样以后再扩展输入参数,直接修改这个类就ok了.        不多说了,先上代码: /** * 请求配置类 * * @author arron * @date 2016年2月2日 下午3:14:32 * @version 1.0 */ public class HttpConfig { private HttpConfig(){}; /**

轻松把玩HttpClient之封装HttpClient工具类(七),新增验证码识别功能

       这个HttpClientUtil工具类分享在GitHub上已经半年多的时间了,并且得到了不小的关注,有25颗star,被fork了38次.有了大家的鼓励,工具类一直也在完善中.最近比较忙,两个多月前的修改在今天刚修改测试完成,今天再次分享给大家.        验证码识别这项技术并不是本工具类的功能,而是通过一个开源的api来识别验证码的.这里做了一个简单的封装,主要是用来解决登陆时的验证码的问题.在线验证码识别官网:http://lab.ocrking.com/,github地址

轻松把玩HttpClient之封装HttpClient工具类(九),添加多文件上传功能

       在Git上有人给我提Issue,说怎么上传文件,其实我一开始就想上这个功能,不过这半年比较忙,所以一直耽搁了.这次正好没什么任务了,赶紧完成这个功能.毕竟作为一款工具类,有基本的请求和下载功能,就差上传了,有点说不过去.好了,天不早了,咱干点正事吧.        如果你只想了解怎么用HttpClient来上传文件,可以参考这篇文章:http://blog.csdn.net/fengyuzhengfan/article/details/39941851,里面写的很清楚了.这里我主要

轻松把玩HttpClient之封装HttpClient工具类(二),插件式配置HttpClient对象

       上一篇文章中,简单分享一下封装HttpClient工具类的思路及部分代码,本文将分享如何实现插件式配置HttpClient对象.        如果你看过我前面的几篇关于HttpClient的文章或者官网示例,应该都知道HttpClient对象在创建时,都可以设置各种参数,但是却没有简单的进行封装,比如对我来说比较重要的3个:代理.ssl(包含绕过证书验证和自定义证书验证).超时.还需要自己写.所以这里我就简单封装了一下,顺便还封装了一个连接池的配置.        其实说是插件式

轻松把玩HttpClient之封装HttpClient工具类(八),优化启用Http连接池策略

       写了HttpClient工具类后,有人一直在问我怎么启用http连接池,其实我没考虑过这个问题.不过闲暇的时候,突然间想起了这个问题,就想把这个问题搞一搞.        之前没用过,但是理解起来应该不算难.作为一个Coder,就算没用过http连接池,但是肯定用过数据库连接池.二者的功能是类似的,就是把建立链接和断开链接的时间节省下来.众所周知,http建立链接是需要3次握手,了解的深入一些的,还知道断开链接需要4次握手.这些操作都是自动完成的,如果我们把这些建立和断开链接的时间