我遇到一个有线问题。 当我调用HttpAsyncClients.excute方法时,如果网络不稳定(无法连接到服务器),则会调用失败的方法。
然后它将调用被阻止的CloseableHttpAsyncClient.close方法。 这使程序出错。 CloseableHttpAsyncClient关闭时如何避免死锁?
下面是代码:
public static void sendPostAsync(String url, String param) {
try {
final CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
httpClient.start();
final HttpPost request = new HttpPost(url);
StringEntity se = new StringEntity(param, "UTF-8");
request.setEntity(se);
request.addHeader(new BasicHeader("Content-Type", "application/json"));
httpClient.execute(request, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
try {
String requestContent = null;
try {
requestContent = EntityUtils.toString(request.getEntity());
} finally {
EntityUtils.consume(request.getEntity());
}
String content = null;
try {
content = EntityUtils.toString(response.getEntity());
} finally {
EntityUtils.consume(response.getEntity());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
close(httpClient);
}
}
public void failed(final Exception ex) {
close(httpClient);
System.out.println(request.getRequestLine() + "->" + ex);
System.out.println(" callback thread id is : " + Thread.currentThread().getId());
}
public void cancelled() {
close(httpClient);
System.out.println(request.getRequestLine() + " cancelled");
System.out.println(" callback thread id is : " + Thread.currentThread().getId());
}
private void close(CloseableHttpAsyncClient client) {
try {
System.out.println("sendPostJsonAsync httpClient.close()");
client.close();//blocked here
} catch (IOException ex) {
}
}
});
} catch (Exception e1) {
logger.error("sendPostJson", e1);
e1.printStackTrace();
}
}
client.close的源代码如下:
@Override
public void close() {
if (this.status.compareAndSet(Status.ACTIVE, Status.STOPPED)) {
if (this.reactorThread != null) {
try {
this.connmgr.shutdown();
} catch (final IOException ex) {
this.log.error("I/O error shutting down connection manager", ex);
}
try {
this.reactorThread.join();
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}