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

简介:        本文主要来分享一下该工具类的测试结果。工具类的整体源码不再单独分享,源码基本上都已经在文章中了。开始我们的测试。       单线程调用测试: public static void testOne() throws HttpProcessException{ System.

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

       单线程调用测试:

	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 httpclientUtil交流

目录
相关文章
|
2月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
48 1
C++ 多线程之初识多线程
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
20 3
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
19 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
32 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
36 1
|
2月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
38 1
|
2月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
28 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
54 6
|
2月前
|
存储 运维 NoSQL
Redis为什么最开始被设计成单线程而不是多线程
总之,Redis采用单线程设计是基于对系统特性的深刻洞察和权衡的结果。这种设计不仅保持了Redis的高性能,还确保了其代码的简洁性、可维护性以及部署的便捷性,使之成为众多应用场景下的首选数据存储解决方案。
42 1