`

[转]多线程情况下HttpClient的使用

阅读更多

本文转截自:http://www.thinkingquest.net/articles/210.html

 

3.x版本的httpclient属于apache的commons项目。 从4.x开始,httpclient被转移到了httpcomponent项目下。 api也发生了重大的变化。 http 3.x已经不推荐使用。使用3.x版本的地方,官方建议都升级到4.x版本。

本文的api也都基于4.x版本。下面是一个最simple的案例:

private String upload(String url, HttpEntity entity) {
    String result = null;
     
    HttpClient httpClient = new DefaultHttpClient();
     
    try {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);
         
        HttpResponse response = httpClient.execute(httpPost);
        int status = response.getStatusLine().getStatusCode();
        if (status == HttpStatus.SC_OK) {
            HttpEntity resEntity = response.getEntity();
            result = EntityUtils.toString(resEntity, "UTF-8");
        } else {
            logger.error("upload:" + url + " error code:" + status);
        }
    } catch (Exception ex) {
        logger.error("Error with HttpClient ", ex);
    } finally {
        try {
            httpClient.getConnectionManager().shutdown();
        } catch (Exception ignore) {}
    }
     
    return result;
 
}

在这段代码中,每调用一次upload方法,都会new一次 BasicHttpClient对象。由此产生一个疑问,这个对象是否是线程安全的呢?查阅了文档,文档中说它是线程安全的。文档地 址:http://hc.apache.org/httpcomponents-client-ga/tutorial/html /httpagent.html

实测对一个BasicHttpClient对象,多个线程调用,只有一个线程运行正常,其他线程全部抛出异常。究其根源,是其中的ConnectionManager的问题。
在多线程的情况下,如果创建一个BasicHttpClient对象,代码应该如下:

PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
 
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
 
BasicHttpParams params = new BasicHttpParams();
params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);
params.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 64 * 1024);
 
client = new DefaultHttpClient(cm, params);

 

每次执行client.execute(method)之后,需要调用method的releaseConnection()方法。

PoolingClientConnectionManager是其中的关键,替代了默认采用的BasicClientConnectionManager。这样就可以多线程。
setMaxTotal设置的是最大连接数。如果不设置,默认值为20。defaultMaxPerRoute的默认值是2。文档中说,这两个参数过于保守。对于频繁请求的应用来说,都太小了。
关于其它的参数可以参见文档:

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e399

 

本文转截自:http://www.thinkingquest.net/articles/210.html

----

PS:

可以使用method的abort方法 哎~~

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics