HttpClient4.x之前没有连接池的概念,多少次请求就会建立多少个IO,在访问量巨大的情况下服务器的IO可能会耗尽。最新HttpClient4.2有连接池的东西在里头,使用PoolingClientConnectionManager,具体可以参考官方文档,里面有详细介绍。
关于PoolingClientConnectionManager 介绍原文是这样的:
PoolingClientConnectionManager
is a more complex implementation that manages a pool of client connections and is able to service connection requests from multiple execution threads. Connections are pooled on a per route basis. A request for a route for which the manager already has a persistent connection available in the pool will be serviced by leasing a connection from the pool rather than creating a brand new connection.
PoolingClientConnectionManager
maintains a maximum limit of connections on a per route basis and in total. Per default this implementation will create no more than 2 concurrent connections per given route and no more 20 connections in total. For many real-world applications these limits may prove too constraining, especially if they use HTTP as a transport protocol for their services. Connection limits can be adjusted using the appropriate HTTP parameters.
示例:
HttpConnectionManager.java
public class HttpConnectionManager {
private static HttpParams httpParams;
private static PoolingClientConnectionManager cm;
/**
* 最大连接数
*/
public final static int MAX_TOTAL_CONNECTIONS = 200;
/**
* 获取连接的最大等待时间
*/
public final static int WAIT_TIMEOUT = 60000;
/**
* 每个路由最大连接数
*/
public final static int MAX_ROUTE_CONNECTIONS = 300;
/**
* 连接超时时间
*/
public final static int CONNECT_TIMEOUT = 10000;
/**
* 读取超时时间
*/
public final static int READ_TIMEOUT = 10000;
static {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http",80,PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(
new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
cm = new PoolingClientConnectionManager(schemeRegistry);
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(80);
HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,CONNECT_TIMEOUT);
params.setParameter(CoreConnectionPNames.SO_TIMEOUT, READ_TIMEOUT);
}
public static HttpClient getHttpClient() {
return new DefaultHttpClient(cm, httpParams);
}
}
DownloadTask.java
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.params.CoreConnectionPNames;
public class DownloadTask implements Runnable {
private HttpClient httpClient = HttpConnectionPoolManager.getHttpClient();
@Override
public void run() {
String url = "http://www.baidu.com";
download(url);
}
public void download(String url) {
HttpGet httpget = null;
InputStream in = null;
try {
httpget = new HttpGet(url);
httpget.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.79 Safari/537.1");
httpget.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpget.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,1000 * 20);
HttpResponse resp = httpClient.execute(httpget);
int respCode = resp.getStatusLine().getStatusCode();
if (respCode == HttpStatus.SC_OK) {
HttpEntity entity = resp.getEntity();
if (entity != null) {
in = entity.getContent();
sleep(1000);
System.out.println("请求成功了..."
+ Thread.currentThread().getName() + url);
}
} else {
System.out.println("请求失败了..."
+ Thread.currentThread().getName() + url);
if(httpget!=null)
httpget.abort();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
if(httpget!=null)
httpget.abort();
} catch (IOException e) {
e.printStackTrace();
if(httpget!=null)
httpget.abort();
} catch (Exception e) { // 捕获最大的异常
e.printStackTrace();
if(httpget!=null)
httpget.abort();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void sleep(int time) throws InterruptedException {
Thread.sleep(time);
}
}
测试类
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
for(int i=0;i<8;i++){
new Thread(new DownloadTask()).start();
}
}
}