我正在尝试使用并发发送未定义数量的HTTP Rest请求。这是基本的代码框架:
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(maxConn);
connManager.setDefaultMaxPerRoute(maxConn);
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).build();
ExecutorService es = Executors.newFixedThreadPool(maxConn);
for (...){
es.execute(new RequestThread(httpclient, ...other data for creating a request...));
}
es.shutdown();
es.awaitTermination(timeout, TimeUnit.SECONDS);
//Tested timeout = 30
httpclient.close();
而 RequestThread 的基本代码是:
public class RequestThread implements Runnable {
public RequestThread(CloseableHttpClient httpclient, ..other neccesay data..){
...
}
@Override
public void run() {
try {
processRequest(httpclient, ...);
// In this method, each CloseableHttpResponse is consumed and closed properly.
} catch (Exception e) {
e.printStackTrace();
}
}
它会多次抛出此异常:
java.lang.IllegalStateException: Connection pool shut down
at org.apache.http.util.Asserts.check(Asserts.java:34)
at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
at com.ericsson.http.DMHttpCommunicationManager.executeRequestMethod(DMHttpCommunicationManager.java:109)
at com.ericsson.http.RequestThread.processRequest(RequestThread.java:39)
at com.ericsson.http.RequestThread.run(RequestThread.java:25)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
似乎主线程关闭得太快,导致创建的可运行对象引发这些异常。
有没有办法强制执行器服务等待可运行对象完成(在关闭 HttpClient 之前)?我应该使用其他策略吗?
提前谢谢。
问候。
尝试更改此行代码;
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).build();
自;
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).setConnectionManagerShared(true).build();
当我遇到这个线程时,我遇到了类似的错误,这似乎为我解决了这个问题。我知道这是一个老问题,但为其他人添加想法以供将来参考。
我不是 100% 确定为什么此修复程序有效,因为围绕此的文档非常糟糕。为了得到这个解决方案,我对我正在测试的内容进行了大量的试验和错误。不过,从我所能收集到的信息来看,此修复程序之所以有效,是因为它随后在后台使用共享连接池,这意味着连接保持开放状态以供使用。