java - 在多线程环境中使用 HttpClient 的最佳实践

标签 java apache-commons-httpclient

一段时间以来,我一直在多线程环境中使用 HttpClient。对于每一个线程,在发起连接时,都会创建一个全新的 HttpClient 实例。

最近发现,使用这种方式会导致用户打开的端口过多,大部分连接处于TIME_WAIT状态。

http://www.opensubscriber.com/message/commons-httpclient-dev@jakarta.apache.org/86045.html

因此,不是每个线程都在做:

HttpClient c = new HttpClient();
try {
    c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
}

我们计划:

[方法 A]

// global_c is initialized once through
// HttpClient global_c = new HttpClient(new MultiThreadedHttpConnectionManager());

try {
    global_c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
}

在正常情况下,global_c 将被 50++ 个线程同时访问。我想知道,这会产生任何性能问题吗? MultiThreadedHttpConnectionManager 是否使用无锁机制来实现其线程安全策略?

如果有 10 个线程在使用 global_c,其他 40 个线程会被锁定吗?

或者,如果我在每个线程中创建一个 HttpClient 的实例,但显式释放连接管理器会更好吗?

[方法 B]

MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager();
HttpClient c = new HttpClient(connman);
try {
      c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
    connman.shutdown();
}

connman.shutdown() 会遇到性能问题吗?

对于使用 50++ 线程的应用程序,我可以知道哪种方法(A 或 B)更好吗?

最佳答案

绝对是方法 A,因为它是池化和线程安全的。

如果您使用的是 httpclient 4.x,则连接管理器称为 ThreadSafeClientConnManager。看到这个link有关更多详细信息(向下滚动到“池连接管理器”)。例如:

    HttpParams params = new BasicHttpParams();
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, registry);
    HttpClient client = new DefaultHttpClient(cm, params);

关于java - 在多线程环境中使用 HttpClient 的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1281219/

相关文章:

java - 导航案例在 JSF 中不起作用

java - 控制台中显示奇怪的输出,尝试通过站点中的 java 登录

java - Java 中使用 commons HttpClient 的curl 等效项

java - 在http get请求中设置对象

Java LIBGDX,从另一个类调用InputHandler的TouchDown方法

java - @EnableWebMvc 上的 Spring 条件 bean

java - IDEA 10.0.3 在重构时用完全限定名替换声明

java - if 语句中的多个字符串条件

java - 使用 Apache commons HttpClient 时如何覆盖请求中的 "Host" header

ssl - 配置 WebSphere 8 SSL(应用程序之间的 HTTPS)