應用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();
就如許!