CompletableFuture Timeouts in Java
Futures and timeouts — seems like the start of a weird sci-fi movie. Let's take a look at how JDK 9 improves on JDK 8's CompletableFuture. Click here for more!
Join the DZone community and get the full member experience.
Join For FreeAs much as I love Java 8's CompletableFuture, it has its downsides, specifically the idiomatic handling of timeouts.
Luckily, JDK 9 brought two new methods that provide the functionality developers longed for — the ExecutionException
. This is crucial for ensuring the proper resiliency when working with asynchronous processing.
In this article, I will try to raise the awareness of the new crucial API methods.
Simply put, after calling the above method, CompletableFuture
, the future will throw an ExecutionException
as long as it doesn't complete within a specified timeout.
Take a look at this simple example:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(this::computeEndlessly)
.orTimeout(1, TimeUnit.SECONDS);
future.get(); // java.util.concurrent.ExecutionException after waiting for 1 second
In this example, we can return a default value once the timeout is reached:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(this::computeEndlessly)
.completeOnTimeout(42, 1, TimeUnit.SECONDS);
Integer result = future.get(); // 42
See? It is as simple as that. Although, I don't necessarily like the fact that we're always forced to precompute the default value. If you look at the signature, you will see that the value isn't computed lazily:
public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
This could've been easily achieved, for example, by providing an alternative API method that accepted Supplier<T> instead of plain T. For more about this alternative API method, you can find more here.
The complete example can be found on GitHub.
Published at DZone with permission of Grzegorz Piwowarek, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments