Asynchronous non-blocking task with CompletableFutures
Great question. Yes a CompleteableFuture
is perfect for your needs! Lets investigate further the functionality of the class.
A CompleteableFuture
is a wrapper for the Future
class and allows for executing in parallel. Lets take a look at an example from this article.
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Result of the asynchronous computation";
});
In the above example, the program will start the CompletableFuture
asynchronously and will have the new thread sleep in the background. If we add .thenApply()
seen below:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Result of the asynchronous computation";
}).thenApply(result -> {
System.out.println(result);
return "Result of the then apply";
});
The application will execute just as we discussed before, but once it completes (non-exceptionally) the current thread running the supplyAsync
will execute the print statement.
Note, if a synchronous transformation is added to a future after it has finished execution, the calling thread will perform the transformation. As we see below:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Result of the asynchronous computation";
});
// Long calculations that allows the future above to finish
future.thenApply(result -> {
System.out.println(result);
return "Result of the then apply";
});
the thenApply
will run on the thread that runs future.thenApply(...)
, not the thread spawned to run the supplyAsync
in the background.