1

I am trying to use AsyncHttpClient in order to send multiple requests at once, add each response to a list, and then do some logic on the list once all responses have come back.

So far I have:

//I have a private static ArrayList<String> lists that I am hoping
//to use to concatenate all responses into one list with

private static ArrayList<String> lists;

/*
 * @param bodies - an array list of the bodies I will be iterating through (as JSON strings) to add a different body to each post request
 * @param url - the url to send post request to
 */
public void makeTheCalls(ArrayList<String> bodies, String url) {
    AsyncHttpClient client = asyncHttpClient();
    for (int idx = 0; idx < bodies.size(); idx++) {
        client.preparePost(url).setBody(bodies.get(idx)).execute(new AsyncCompletionHandler<Void>() {
            @Override
            public Void onCompleted(Response response) throws exception {
                // map the response to my POJO for this particular response
                MyClass obj = objectMapper.readValue(response.getResponseBody(), MyClass.class);
                //print the ArrayList<String> i want to concat to my master list
                System.out.println(obj.getMyField());
                lists.addAll(obj.getMyfield());
                return null;
            }
        });
    }
    System.out.println(lists.size());
}

This seems to be making all of my post requests asynchronously and it is even printing each of my response correctly. But when I try to use the 'lists' field later on, like when I try to print lists.size(), it seems to be empty still.

Does this code correctly use a static field to allow each thread to edit the same instance? Is the logic with the 'lists' array happening before the responses are coming back? (if so how can i get the logic to delay until all requests have come back while keeping the calls asynchronous?

____________________ANSWER__________________

the application was making all the async requests, and then continuing before the responses were coming back. The use of a CountDownLatch solved this issue

//I have a private static ArrayList<String> lists that I am hoping
//to use to concatenate all responses into one list with

private static ArrayList<String> lists;

/*
 * @param bodies - an array list of the bodies I will be iterating through (as JSON strings) to add a different body to each post request
 * @param url - the url to send post request to
 */
public void makeTheCalls(ArrayList<String> bodies, String url) {
    final CountDownLatch latch = new CountDownLatch(bodies.size());
    AsyncHttpClient client = asyncHttpClient();
    for (int idx = 0; idx < bodies.size(); idx++) {
        client.preparePost(url).setBody(bodies.get(idx)).execute(new AsyncCompletionHandler<Void>() {
            @Override
            public Void onCompleted(Response response) throws exception {
                // map the response to my POJO for this particular response
                MyClass obj = objectMapper.readValue(response.getResponseBody(), MyClass.class);
                //print the ArrayList<String> i want to concat to my master list
                System.out.println(obj.getMyField());
                lists.addAll(obj.getMyfield());
                return null;
            }
        });
    }
    latch.await();
    client.close();
    System.out.println(lists.size());
}
skyleguy
  • 979
  • 3
  • 19
  • 35

1 Answers1

2

Since execution is asynchronous, your code continues to print the content of the lists before the callback(s) actually fill it. You could use a CountDownLatch (see example 3 here) to ensure all requests are over before printing the contents.

Additionally, I'd also modify the code to make sure the lists variable is thread safe.

Bahaa
  • 1,577
  • 18
  • 31
  • yes after some more testing i realized that it prints 0 after sending all my requests, then the printing of the responses comes in. I will certainly try and use a count down latch. Any particular way you would go about making the lists variable thread safe? – skyleguy Dec 11 '18 at 20:30
  • Check this answer for how to make the list thread safe: https://stackoverflow.com/a/2444195/1662819 – Bahaa Dec 11 '18 at 20:33
  • Thanks for all the help. The CountDownLatch worked like a charm – skyleguy Dec 11 '18 at 20:41