转:http://www.cnblogs.com/wasp520/archive/2012/06/28/2568897.html
使用httpClient可模拟请求Url获取资源,使用单线程的请求速度上会有一定的限制,参考了Apache给出的例子,自己做了测试实现多线程并发请求,以下代码需要HttpClient 4.2的包,可以在http://hc.apache.org/downloads.cgi下载
1、并发请求
package generate.httpclient; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; public class ThreadPoolHttpClient { // 线程池 private ExecutorService exe = null; // 线程池的容量 private static final int POOL_SIZE = 20; private HttpClient client = null; String[] urls=null; public ThreadPoolHttpClient(String[] urls){ this.urls=urls; } public void test() throws Exception { exe = Executors.newFixedThreadPool(POOL_SIZE); HttpParams params =new BasicHttpParams(); /* 从连接池中取连接的超时时间 */ ConnManagerParams.setTimeout(params, 1000); /* 连接超时 */ HttpConnectionParams.setConnectionTimeout(params, 2000); /* 请求超时 */ HttpConnectionParams.setSoTimeout(params, 4000); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register( new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); //ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); PoolingClientConnectionManager cm=new PoolingClientConnectionManager(schemeRegistry); cm.setMaxTotal(10); final HttpClient httpClient = new DefaultHttpClient(cm,params); // URIs to perform GETs on final String[] urisToGet = urls; /* 有多少url创建多少线程,url多时机子撑不住 // create a thread for each URI GetThread[] threads = new GetThread[urisToGet.length]; for (int i = 0; i < threads.length; i++) { HttpGet httpget = new HttpGet(urisToGet[i]); threads[i] = new GetThread(httpClient, httpget); } // start the threads for (int j = 0; j < threads.length; j++) { threads[j].start(); } // join the threads,等待所有请求完成 for (int j = 0; j < threads.length; j++) { threads[j].join(); } 使用线程池*/ for (int i = 0; i < urisToGet.length; i++) { final int j=i; System.out.println(j); HttpGet httpget = new HttpGet(urisToGet[i]); exe.execute( new GetThread(httpClient, httpget)); } //创建线程池,每次调用POOL_SIZE /* for (int i = 0; i < urisToGet.length; i++) { final int j=i; System.out.println(j); exe.execute(new Thread() { @Override public void run() { this.setName("threadsPoolClient"+j); try { this.sleep(100); System.out.println(j); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } HttpGet httpget = new HttpGet(urisToGet[j]); new GetThread(httpClient, httpget).get(); } }); } */ //exe.shutdown(); System.out.println("Done"); } static class GetThread extends Thread{ private final HttpClient httpClient; private final HttpContext context; private final HttpGet httpget; public GetThread(HttpClient httpClient, HttpGet httpget) { this.httpClient = httpClient; this.context = new BasicHttpContext(); this.httpget = httpget; } @Override public void run(){ this.setName("threadsPoolClient"); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } get(); } public void get() { try { HttpResponse response = this.httpClient.execute(this.httpget, this.context); HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println(this.httpget.getURI()+": status"+response.getStatusLine().toString()); } // ensure the connection gets released to the manager EntityUtils.consume(entity); } catch (Exception ex) { this.httpget.abort(); }finally{ httpget.releaseConnection(); } } } }
2、多线程异步请求
package generate.httpclient; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.concurrent.FutureCallback; import org.apache.http.impl.nio.client.DefaultHttpAsyncClient; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.reactor.IOReactorException; public class AsynClient{ /** * @param args * @throws IOReactorException * @throws InterruptedException */ private List<String> urls; private HandlerFailThread failHandler; public AsynClient(List<String> list){ failHandler=new HandlerFailThread(); urls=list; } public Map<String,String> asynGet() throws IOReactorException, InterruptedException { final HttpAsyncClient httpclient = new DefaultHttpAsyncClient(); httpclient.start(); int urlLength=urls.size(); HttpGet[] requests = new HttpGet[urlLength]; int i=0; for(String url : urls){ requests[i]=new HttpGet(url); i++; } final CountDownLatch latch = new CountDownLatch(requests.length); final Map<String, String> responseMap=new HashMap<String, String>(); try { for (final HttpGet request : requests) { httpclient.execute(request, new FutureCallback<HttpResponse>() { public void completed(final HttpResponse response) { latch.countDown(); responseMap.put(request.getURI().toString(), response.getStatusLine().toString()); try { System.out.println(request.getRequestLine() + "->" + response.getStatusLine()+"->"); //+readInputStream(response.getEntity().getContent()) } catch (IllegalStateException e) { failHandler.putFailUrl(request.getURI().toString(), response.getStatusLine().toString()); e.printStackTrace(); } catch (Exception e) { failHandler.putFailUrl(request.getURI().toString(), response.getStatusLine().toString()); e.printStackTrace(); } } public void failed(final Exception ex) { latch.countDown(); ex.printStackTrace(); failHandler.putFailUrl(request.getURI().toString(), ex.getMessage()); } public void cancelled() { latch.countDown(); } }); } System.out.println("Doing..."); } finally { latch.await(); httpclient.shutdown(); } System.out.println("Done"); failHandler.printFailUrl(); return responseMap; } private String readInputStream(InputStream input) throws IOException{ byte[] buffer = new byte[128]; int len = 0; ByteArrayOutputStream bytes = new ByteArrayOutputStream(); while((len = input.read(buffer)) >= 0) { bytes.write(buffer, 0, len); } return bytes.toString(); } /** * Test * @param args */ public static void main(String[] args) { List<String> urls=new ArrayList<String>(); urls.add("http://127.0.0.1/examples/servlets/"); urls.add("http://127.0.0.1/examples/servlets/"); urls.add("http://127.0.0.1/examples/servlets/"); for(int i=0;i<10;i++){ urls.addAll(urls); } System.out.println(urls.size()); AsynClient client=new AsynClient(urls); try { client.asynGet(); } catch (IOReactorException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("done"); } }
创建一个线程记录失败的请求
package generate.httpclient; import java.util.HashMap; import java.util.Map; public class HandlerFailThread extends Thread{ Map<String, String> failUrl=new HashMap<String, String>(); public void putFailUrl(String url,String status){ synchronized (failUrl) { failUrl.put(url,status); } } @Override public void run() { while(true){ } } public void printFailUrl(){ for(Map.Entry<String, String> m: failUrl.entrySet()){ System.out.println("****fail:url:"+m.getKey()+ " code :"+m.getValue()); } } }
异步请求,也可通过pool管理,例如
ConnectingIOReactor nio=new DefaultConnectingIOReactor();
PoolingClientAsyncConnectionManager manager=new PoolingClientAsyncConnectionManager(nio);
manager.setMaxTotal(1000);
manager.setDefaultMaxPerRoute(100);
HttpParams params=new BasicHttpParams();
/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 10000);
/* 请求超时 */
HttpConnectionParams.setSoTimeout(params, 60*1000);
DefaultHttpAsyncClient.setDefaultHttpParams(params);
final HttpAsyncClient httpclient = new DefaultHttpAsyncClient(manager);
httpclient.start();
HttpClient相关可参看,里面有很多说明与例子
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
相关推荐
本篇文章将深入探讨如何使用HTTPClient进行多线程分段下载的实践。 首先,我们要理解多线程下载的基本原理。多线程下载是通过将大文件分割成多个小段,每个线程负责下载一个或多个段,这样可以充分利用多核处理器的...
4、多线程下载:使用RandomAccessFile输出流写 5、多线程下载-断点续传:使用临时文件记录当前下载的数据,下次读取文件开始下载 6、下载显示进度条-ProgressBar 7、在gitbub上面下载已经有支持断点续传功能的代码...
在Android系统中,由于主线程不能执行耗时操作,否则会引发ANR(Application Not Responding)错误,因此利用HttpClient的多线程特性,可以将网络请求放到后台线程,保证UI的流畅性。 HttpClient的使用步骤通常包括...
标题中的“用HttpClient写了一个多线程下载软件”意味着我们将探讨如何使用Apache HttpClient库来创建一个支持多线程的文件下载应用。HttpClient是一个强大的Java库,它提供了丰富的HTTP客户端功能,包括请求发起、...
6. **线程安全**:如果涉及到多线程环境,文章可能还会讨论如何确保HttpClient的线程安全性,因为HttpClient是为高并发设计的,不应频繁创建和销毁。 7. **其他实用功能**:可能还会涵盖添加身份验证信息,处理响应...
通过使用HttpClient的连接池和多线程,我们可以有效地并发执行HTTP GET请求,同时控制并发数量,避免过多的网络连接导致服务器压力过大。这种方式提高了请求效率,减少了资源消耗,并且遵循了最佳实践。
在多线程环境下,HttpClient可以有效地处理并发请求,提高应用程序的性能。 在Spring框架中整合HttpClient,通常会创建一个自定义的HttpClinet工具类,如`HttpClientUtil.java`所示。这个工具类可能包含静态方法,...
本文将详细讲解如何使用HTTPClient进行POST请求,并探讨在多线程环境下的应用,以及与"Grabticket"这个场景相关的实践。 HTTPClient是由Apache基金会开发的一个开源库,它提供了强大的功能来执行HTTP请求,包括GET...
在这个小例子中,我们将讨论如何利用HttpClient实现多线程下载,以提高文件下载效率。 首先,我们需要在项目中引入Apache HttpClient的相关依赖。在Maven项目中,可以在pom.xml文件中添加以下依赖: ```xml ...
这通常在程序开始时完成,因为HttpClient是线程安全的,可以重复使用。 ```java CloseableHttpClient httpClient = HttpClients.createDefault(); ``` 2. **创建HttpGet或HttpPost对象**: 根据你的需求,你可以...
本篇将详细讲解如何使用`HttpClient`进行异步请求数据,并结合Android的`AsyncTask`来处理后台任务,避免阻塞UI线程。 首先,理解`HttpClient`的基本使用方法。`HttpClient`包含几个关键组件,如`HttpClient`实例、...
// 使用CountDownLatch来同步多个线程,确保所有请求完成后再执行其他操作 final CountDownLatch latch = new CountDownLatch(requests.length); try { // 遍历所有请求,使用execute方法异步发送 for (final ...
HttpClient的优势在于其强大的功能,如支持多种HTTP方法、自动处理重定向、线程安全、易于配置和扩展。它还提供了更高级的特性,如Cookie管理、连接池、超时控制等。对于复杂的HTTP交互或性能要求高的应用,...
在C#中,我们可以使用`System.Net.WebClient`类或者自定义`HttpClient`实例来实现多线程下载。 异步编程是现代C#的一个重要特性,它允许我们在等待IO操作完成时,不阻塞主线程,提高程序的响应性。在下载工具中,...
在本主题中,我们将深入探讨如何利用HttpClient实现异步请求数据,并结合Android的Asynctask进行多线程处理,以避免阻塞UI线程。 首先,我们需要理解HttpClient的基本使用。HttpClient的核心组件包括`HttpClient`...
HttpClient下载数据 图片,string 使用get请求数据
在处理大量并发请求或需要...正确地结合使用`HttpClient`、异步编程、线程池和并发控制,可以构建出高效、稳定的多线程HTTP请求处理系统。在实际开发中,需要根据具体需求灵活运用这些技术,确保程序的性能和可靠性。
5. **线程安全**:为了在多线程环境中安全使用,`HttpClientUtils`需要确保其方法是线程安全的,避免并发问题。 而`RestClient`类可能封装了更高级的功能,比如: 1. **构建REST请求**:提供方法来构建带参数的URL...
Java 模拟多线程 HTTP 请求代码分享 本篇文章分享了 Java 模拟多线程 HTTP 请求的相关...同时,本篇文章也提供了多种相关知识点的解释,包括多线程编程、HTTP 请求、Apache HttpClient 库和 ExecutorService 框架等。
HttpClient提供了对多线程请求执行的支持。 第三章 HTTP状态管理 HTTP状态管理主要涉及到管理HTTP请求和响应的状态。在这一章节中,我们将介绍cookies的处理、选择Cookie策略和自定义Cookie策略,以及如何持久化...