程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 應用java的HttpClient完成多線程並發

應用java的HttpClient完成多線程並發

編輯:關於JAVA

應用java的HttpClient完成多線程並發。本站提示廣大學習愛好者:(應用java的HttpClient完成多線程並發)文章只能為提供參考,不一定能成為您想要的結果。以下是應用java的HttpClient完成多線程並發正文


解釋:以下的代碼基於httpclient4.5.2完成。

我們要應用java的HttpClient完成get要求抓取網頁是一件比擬輕易完成的任務:

  public static String get(String url) {
    CloseableHttpResponseresponse = null;
    BufferedReader in = null;
    String result = "";
    try {
      CloseableHttpClienthttpclient = HttpClients.createDefault();
      HttpGethttpGet = new HttpGet(url);
      response = httpclient.execute(httpGet);
 
      in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
      StringBuffersb = new StringBuffer("");
      String line = "";
      String NL = System.getProperty("line.separator");
      while ((line = in.readLine()) != null) {
        sb.append(line + NL);
      }
      in.close();
      result = sb.toString();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (null != response) response.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }

要多線程履行get要求時下面的辦法也堪用。不外這類多線程要求是基於在每次挪用get辦法時創立一個HttpClient實例完成的。每一個HttpClient實例應用一次即被收受接管。這明顯不是一種最優的完成。

HttpClient供給了多線程要求計劃,可以檢查官方文檔的《 Pooling connection manager 》這一節。HttpCLient完成多線程要求是基於內置的銜接池完成的,個中有一個症結的類即PoolingHttpClientConnectionManager,這個類擔任治理HttpClient銜接池。在PoolingHttpClientConnectionManager中供給了兩個症結的辦法:setMaxTotal和setDefaultMaxPerRoute。setMaxTotal設置銜接池的最年夜銜接數,setDefaultMaxPerRoute設置每一個路由上的默許銜接個數。另外還有一個辦法setMaxPerRoute——零丁為某個站點設置最年夜銜接個數,像如許:

   HttpHosthost = new HttpHost("locahost", 80);
   cm.setMaxPerRoute(new HttpRoute(host), 50);

依據文檔稍稍調劑下我們的get要求完成:

package com.zhyea.robin;
 
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class HttpUtil {
 
  private static CloseableHttpClienthttpClient;
 
  static {
    PoolingHttpClientConnectionManagercm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(20);
    cm.setDefaultMaxPerRoute(50);
    httpClient = HttpClients.custom().setConnectionManager(cm).build();
  }
 
  public static String get(String url) {
    CloseableHttpResponseresponse = null;
    BufferedReaderin = null;
    String result = "";
    try {
 
      HttpGethttpGet = new HttpGet(url);
      response = httpClient.execute(httpGet);
 
      in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
      StringBuffersb = new StringBuffer("");
      String line = "";
      String NL = System.getProperty("line.separator");
      while ((line = in.readLine()) != null) {
        sb.append(line + NL);
      }
      in.close();
      result = sb.toString();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (null != response) response.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }
 
  public static void main(String[] args) {
    System.out.println(get("https://www.百度.com/"));
  }
}

如許就差不多了。不外關於我本身而言,我更愛好httpclient的fluent完成,好比我們適才完成的http get要求完整可以如許簡略的完成:

package com.zhyea.robin;
 
import org.apache.http.client.fluent.Request;
import java.io.IOException;
 
public class HttpUtil {
 
  public static String get(String url) {
    String result = "";
    try {
      result = Request.Get(url)
          .connectTimeout(1000)
          .socketTimeout(1000)
          .execute().returnContent().asString();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return result;
  }
 
  public static void main(String[] args) {
    System.out.println(get("https://www.百度.com/"));
  }
}

我們要做的只是將之前的httpclient依附調換為fluent-hc依附:

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>fluent-hc</artifactId>
   <version>4.5.2</version>
</dependency>

而且這個fluent完成自然就是采取PoolingHttpClientConnectionManager完成的。它設置的maxTotal和defaultMaxPerRoute的值分離是200和100:

    CONNMGR = new PoolingHttpClientConnectionManager(sfr);
    CONNMGR.setDefaultMaxPerRoute(100);
    CONNMGR.setMaxTotal(200);

獨一一點讓人不爽的就是Executor沒有供給調劑這兩個值的辦法。不外這也完整夠用了,其實不可的話,還可以斟酌重寫Executor辦法,然後直接應用Executor履行get要求:

Executor.newInstance().execute(Request.Get(url))
        .returnContent().asString();

就如許!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved