0

I meet a wired question. When I call HttpAsyncClients.excute method, if the net is unstable (can't connect to the server), the failed method will be called.

Then it will call CloseableHttpAsyncClient.close method which is blocked. That makes the program wrong. How to avoid the deadlock when CloseableHttpAsyncClient close?

Below is the code:

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();
    }
}

The source code of client.close is as below:

    @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();
            }
        }
    }
}
roast_soul
  • 3,554
  • 7
  • 36
  • 73

0 Answers0