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