`
fackyou200
  • 浏览: 310962 次
  • 性别: Icon_minigender_1
  • 来自: 山西太原
社区版块
存档分类
最新评论

httpClient多线程请求

 
阅读更多

转: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多线程下载(分段下载)实践

    本篇文章将深入探讨如何使用HTTPClient进行多线程分段下载的实践。 首先,我们要理解多线程下载的基本原理。多线程下载是通过将大文件分割成多个小段,每个线程负责下载一个或多个段,这样可以充分利用多核处理器的...

    android 学习笔记6-HttpClient 多线程下载 断点续传 进度条 源码关联

    4、多线程下载:使用RandomAccessFile输出流写 5、多线程下载-断点续传:使用临时文件记录当前下载的数据,下次读取文件开始下载 6、下载显示进度条-ProgressBar 7、在gitbub上面下载已经有支持断点续传功能的代码...

    httpclient著名的多线程框架

    在Android系统中,由于主线程不能执行耗时操作,否则会引发ANR(Application Not Responding)错误,因此利用HttpClient的多线程特性,可以将网络请求放到后台线程,保证UI的流畅性。 HttpClient的使用步骤通常包括...

    用HttpClient写了一个多线程下载软件

    标题中的“用HttpClient写了一个多线程下载软件”意味着我们将探讨如何使用Apache HttpClient库来创建一个支持多线程的文件下载应用。HttpClient是一个强大的Java库,它提供了丰富的HTTP客户端功能,包括请求发起、...

    对于C#(HttpClient)方式网络请求的封装

    6. **线程安全**:如果涉及到多线程环境,文章可能还会讨论如何确保HttpClient的线程安全性,因为HttpClient是为高并发设计的,不应频繁创建和销毁。 7. **其他实用功能**:可能还会涵盖添加身份验证信息,处理响应...

    使用java的HttpClient实现多线程并发

    通过使用HttpClient的连接池和多线程,我们可以有效地并发执行HTTP GET请求,同时控制并发数量,避免过多的网络连接导致服务器压力过大。这种方式提高了请求效率,减少了资源消耗,并且遵循了最佳实践。

    HttpClient+ Spring实现多线程

    在多线程环境下,HttpClient可以有效地处理并发请求,提高应用程序的性能。 在Spring框架中整合HttpClient,通常会创建一个自定义的HttpClinet工具类,如`HttpClientUtil.java`所示。这个工具类可能包含静态方法,...

    httpclient工具

    本文将详细讲解如何使用HTTPClient进行POST请求,并探讨在多线程环境下的应用,以及与"Grabticket"这个场景相关的实践。 HTTPClient是由Apache基金会开发的一个开源库,它提供了强大的功能来执行HTTP请求,包括GET...

    使用Apache HttpClient实现多线程下载的小例子

    在这个小例子中,我们将讨论如何利用HttpClient实现多线程下载,以提高文件下载效率。 首先,我们需要在项目中引入Apache HttpClient的相关依赖。在Maven项目中,可以在pom.xml文件中添加以下依赖: ```xml ...

    httpClient完整请求Demo

    这通常在程序开始时完成,因为HttpClient是线程安全的,可以重复使用。 ```java CloseableHttpClient httpClient = HttpClients.createDefault(); ``` 2. **创建HttpGet或HttpPost对象**: 根据你的需求,你可以...

    使用HttpClient异步请求数据

    本篇将详细讲解如何使用`HttpClient`进行异步请求数据,并结合Android的`AsyncTask`来处理后台任务,避免阻塞UI线程。 首先,理解`HttpClient`的基本使用方法。`HttpClient`包含几个关键组件,如`HttpClient`实例、...

    java实现HttpClient异步请求资源的方法

    // 使用CountDownLatch来同步多个线程,确保所有请求完成后再执行其他操作 final CountDownLatch latch = new CountDownLatch(requests.length); try { // 遍历所有请求,使用execute方法异步发送 for (final ...

    java.net.URLConnection发送HTTP请求与通过Apache HttpClient发送HTTP请求比较

    HttpClient的优势在于其强大的功能,如支持多种HTTP方法、自动处理重定向、线程安全、易于配置和扩展。它还提供了更高级的特性,如Cookie管理、连接池、超时控制等。对于复杂的HTTP交互或性能要求高的应用,...

    c#异步多线程http文件分块断点续传下载工具

    在C#中,我们可以使用`System.Net.WebClient`类或者自定义`HttpClient`实例来实现多线程下载。 异步编程是现代C#的一个重要特性,它允许我们在等待IO操作完成时,不阻塞主线程,提高程序的响应性。在下载工具中,...

    HttpClient异步请求数据

    在本主题中,我们将深入探讨如何利用HttpClient实现异步请求数据,并结合Android的Asynctask进行多线程处理,以避免阻塞UI线程。 首先,我们需要理解HttpClient的基本使用。HttpClient的核心组件包括`HttpClient`...

    HttpClient下载数据

    HttpClient下载数据 图片,string 使用get请求数据

    C#http的多线程实现

    在处理大量并发请求或需要...正确地结合使用`HttpClient`、异步编程、线程池和并发控制,可以构建出高效、稳定的多线程HTTP请求处理系统。在实际开发中,需要根据具体需求灵活运用这些技术,确保程序的性能和可靠性。

    httpClient请求

    5. **线程安全**:为了在多线程环境中安全使用,`HttpClientUtils`需要确保其方法是线程安全的,避免并发问题。 而`RestClient`类可能封装了更高级的功能,比如: 1. **构建REST请求**:提供方法来构建带参数的URL...

    java模拟多线程http请求代码分享

    Java 模拟多线程 HTTP 请求代码分享 本篇文章分享了 Java 模拟多线程 HTTP 请求的相关...同时,本篇文章也提供了多种相关知识点的解释,包括多线程编程、HTTP 请求、Apache HttpClient 库和 ExecutorService 框架等。

    HttpClient

    HttpClient提供了对多线程请求执行的支持。 第三章 HTTP状态管理 HTTP状态管理主要涉及到管理HTTP请求和响应的状态。在这一章节中,我们将介绍cookies的处理、选择Cookie策略和自定义Cookie策略,以及如何持久化...

Global site tag (gtag.js) - Google Analytics