Category : Java | Sub Category : Java8 Features | By Prasad Bonam Last updated: 2023-11-13 07:49:05 Viewed : 239
Asynchronous programming in Java 8 is facilitated by the introduction of the CompletableFuture
class in the java.util.concurrent
package. CompletableFuture
is designed to work with both functional and imperative programming styles, providing a convenient way to work with asynchronous computations. Here is an overview of asynchronous programming in Java 8 using CompletableFuture
:
Supplying Async Results:
Use CompletableFuture.supplyAsync
to asynchronously supply a result.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World");
Run Async Tasks:
Use CompletableFuture.runAsync
for asynchronous tasks without a result.
javaCompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("Async task"));
Then Apply:
Use thenApply
to apply a function to the result of a CompletableFuture
.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> transformedFuture = future.thenApply(s -> s + " World");
Then Combine:
Use thenCombine
to combine the results of two CompletableFuture
instances.
javaCompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + s2);
Then Accept:
Use thenAccept
to perform an action with the result of a CompletableFuture
without returning a result.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<Void> actionFuture = future.thenAccept(s -> System.out.println("Result: " + s));
Then Compose:
Use thenCompose
for chaining asynchronous computations where the next stage is dependent on the result of the previous stage.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> composedFuture = future.thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));
Exception Handling:
Use exceptionally
or handle
to handle exceptions that occur during the computation.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// Some computation that may throw an exception
throw new RuntimeException("Something went wrong");
});
CompletableFuture<String> resultFuture = future.exceptionally(ex -> "Handled Exception: " + ex.getMessage());
Join or Get:
Use join
or get
to wait for the completion of a CompletableFuture
.
javaCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
String result = future.join(); // or future.get()
All Of:
Use CompletableFuture.allOf
to wait for the completion of all provided CompletableFuture
instances.
javaCompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);
Any Of:
Use CompletableFuture.anyOf
to wait for the completion of any of the provided CompletableFuture
instances.
javaCompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2);
Here is a comprehensive example demonstrating various aspects of asynchronous programming using CompletableFuture
:
javaimport java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
// Creating asynchronous computations
CompletableFuture<String> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> System.out.println("Async task"));
// Combining and chaining asynchronous computations
CompletableFuture<String> transformedFuture = supplyAsyncFuture.thenApply(s -> s + " World");
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + s2);
CompletableFuture<String> exceptionHandledFuture = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Something went wrong");
}).exceptionally(ex -> "Handled Exception: " + ex.getMessage());
// Waiting for completion
String result = supplyAsyncFuture.join();
// Combining multiple futures
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(supplyAsyncFuture, runAsyncFuture, transformedFuture, combinedFuture, exceptionHandledFuture);
// Handling multiple results
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(supplyAsyncFuture, runAsyncFuture, transformedFuture, combinedFuture, exceptionHandledFuture);
// Waiting for completion of all futures
allOfFuture.join();
// Handling the result of any completed future
anyOfFuture.thenAccept(resultObject -> System.out.println("Result of any completed future: " + resultObject));
}
}
This example covers the creation, combination, chaining, exception handling, and waiting for completion of CompletableFuture
instances, as well as handling multiple results with allOf
and anyOf
. It provides a comprehensive overview of asynchronous programming in Java 8 using CompletableFuture
.