How to make asynchronous calls using java

How can we perform a task by multiple threads?

How can we speed up a process to complete the task early?

Well, there are so many ways to improve the performance of the application. In that asynchronous programming is very popular as we no need to wait for task to complete its job. when its done with execution it gives a callback for us till that time other piece of code or next lines of code will be executed.

In this article, we will focus on how it can be done in java and what are the ways to implement it. we will conclude with a sample example of invoking REST endpoint using plain javascript and will try to do the same with Java as well.

The definition of Asynchronous Programming is that a task can be executed at any point of time in the future and nothing will wait for it to complete.

We can gain the benefit of Asynchronous programming by implementing it at reading large files, I/O operations and network calls. These types of operations are not CPU bound which means the main thread does not have to wait for these tasks to complete and can use that valuable CPU time elsewhere.

Lets see an example of async call in javascript

In javascript, we can pass functions as arguments, and return functions from functions. Here, on successful or failure invoke the callback function. Here callbacks were the standard approach for handling asynchronous operations.

Example:

    getData(function(error, data) {
      if (error) {
          console.log(error);
      } else {
          console.log(data.length);
      }
    });

    function getData(callback) {
        const xhr = new XMLHttpRequest();
        xhr.responseType = 'json';
        xhr.onreadystatechange = function() {
            if (xhr.readyState == XMLHttpRequest.DONE) {
                callback(null, xhr.response);
            }
        }
        xhr.open("GET", "https://jsonplaceholder.typicode.com/data");
        try {
            xhr.send();
        } catch (error) {
            callback(error);
        }
    }

In the same way, it can be implemented in java as well. Before jump into example lets see possiblities of implementing async way in java. Java provided support of asynchronous programming in various releases. Here is the list

Java 1 — Runnable’s(like function as argument)

Java 5 — Executors and Futures(like ajax call)

Java 8 — Completable Futures / Completion Stages(It is pretty much similar to Promises within NodeJS)

Java 11 - httpClient.sendAsync for invocation of web services(prerry much similar to callbacks in javascript)

As the first three approaches are familiar to most people so let's see ajax kind of implementation in java as well.

Example:

    final List<URI> uris = Stream.of(
                            "https://www.google.com/",
                            "https://www.github.com/",
                            "https://www.yahoo.com/"
                            ).map(URI::create).collect(toList());      

    HttpClient httpClient = HttpClient.newBuilder()
                            .connectTimeout(Duration.ofSeconds(10))
                            .followRedirects(HttpClient.Redirect.ALWAYS)
                            .build();

    CompletableFuture[] futures = uris.stream()
                                .map(uri -> verifyUri(httpClient, uri))
                                .toArray(CompletableFuture[]::new);     

    CompletableFuture.allOf(futures).join();           

    private CompletableFuture<Void> verifyUri(HttpClient httpClient, 
                                              URI uri) 
    {
        HttpRequest request = HttpRequest.newBuilder()
                                        .timeout(Duration.ofSeconds(5))
                                        .uri(uri)
                                        .build();

        return httpClient.sendAsync(request,HttpResponse.BodyHandlers.ofString())
                            .thenApply(HttpResponse::statusCode)
                            .thenApply(statusCode -> statusCode == 200)
                            .exceptionally(ex -> false)
                            .thenAccept(valid -> 
                            {
                                if (valid) {
                                    System.out.println("[SUCCESS] Verified " + uri);
                                } else {
                                    System.out.println("[FAILURE] Could not " + "verify " + uri);
                                }
                            });                                    
    }

Notice the use of sendAsync() method to send asynchronous requests.

Asynchronous communication is useful if we don’t want to wait for a response. We provide a callback handler, which gets executed when a response is available.

Thanks for reading. Happy learning!!!