How to use CompletableFuture in Java? Example Tutorial

Hello friends, we meet again today on our journey to Java. So I hope you guys are excited about this Java concurrency lesson. Let me ask you guys one thing before we proceed. Do you guys ever wonder about the future? At some point in time, all of you must have thought about it and wondered about different kinds of outcomes. Well, our Java program also wonders about its future tasks so, let us learn today something similar to that! First of all, before jumping onto what a CompletableFuture is, let us first know what a Future in Java is? For guys who know this beforehand, just refresh the concept and for everyone else, let’s understand what it is.

What is a Future in Java?

The outcome of an asynchronous operation is represented by a JavFuture, java.util.concurrent.Future. A Java Future object is returned when the asynchronous job is created. This Future object serves as a handle to the asynchronous task's result.

The outcome of the asynchronous job may be retrieved using the Future object returned when the task was launched.

When we perform some asynchronous task via Future, we can get the results in a Future object via its get method. The get method is blocked until the asynchronous task is completed.


Now, you all must be wondering, that if the get method is blocking, it’s not quite usable. And yes, you guys are thinking right! There are several limitations of Future due to which CompletableFuture was introduced. These limitations were:


Limitations of Future:
  1. Action performing on Future’s result was blocking.
  2. A Future cannot be mutually completed.
  3. No exception handling techniques were provided for Futures.
  4. Multiple Futures were not able to combine


So, CompletableFuture was introduced which overcame these limitations. Let’s see what it is.





What is CompletableFuture in Java?

For asynchronous programming, a CompltableFuture is utilized. Writing non-blocking code is referred to as asynchronous programming. It does a job on a thread distinct from the main application thread and informs the main thread of its progress, completion, or failure.


As a result, the main thread does not block or wait for the job to finish. Other tasks run in the background. Parallelism increases the program's performance.

In Java, a CompletableFuture is a class. It is a component of java.util.concurrent package. CompletionStage and Future interfaces are implemented.

CompletableFuture in Java with Example - Tutorial




CompletableFuture usage code and example:


Let’s see how we can create a CompletableFuture in Java and use it.

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CompletableFutureDemo {

public Future<String> calculateAsync() throws InterruptedException {
CompletableFuture<String> completableFutureexample = new CompletableFuture<>();

Executors.newCachedThreadPool().submit(() -> {
Thread.sleep(500);
completableFutureexample.complete("Hello");
return null;
});

return completableFutureexample;
}

public static void main(String[] args) {
CompletableFutureDemo demo = new CompletableFutureDemo();
try{
Future<String> completableFuture = demo.calculateAsync();
long t1 = System.currentTimeMillis();
System.out.println("current time:"+t1);
String result = completableFuture.get();
System.out.println(result);
long t2 = System.currentTimeMillis();
System.out.println("current time:"+t2);
System.out.println("tim required : "+(t2-t1));

} catch (Exception e) {
e.printStackTrace();
}

}

}


Output:


Java CompletableFuture Example



There are a few important methods to note in CompletableFuture. Let us see some of them.


CompletableFuture usage code:


import java.util.concurrent.CompletableFuture;

public class CompletableFutureDemo {

public static void main(String[] args) {
try{
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "CourseHero");
long t1 = System.currentTimeMillis();
System.out.println("current time:"+t1);
String result = completableFuture.get();
System.out.println(result);
long t2 = System.currentTimeMillis();
System.out.println("current time:"+t2);
System.out.println("tim required : "+(t2-t1));

} catch (Exception e) {
e.printStackTrace();
}

}

}


Output:


Java Completable Future Example



Observe that we can supply the async task directly to CompletableFuture rather than giving it to executors. The above code shows the same. 


There are also a few more methods that are very useful in CompletableFuture, discussing each in detail is out of scope for this article but we will list them down and describe them.


  1. join() method - When the method is finished, it returns the result value. If finished unusually, it additionally throws a CompletionException (unchecked exception).

  2. supply sync() method - It does its task in an asynchronous manner. A task from ForkJoinPool runs the result of the supplier. As a default, use commonPool(). The supplyAsync() function produces a CompletableFuture to which additional methods can be applied.

  3. thenApply() method - The method thenApply() accepts function as an input. When this stage completes normally, it returns a new CompletableStage. The provided function takes the new stage as an argument.

You might be asking why - well, I'm aware that the runAsync() and supplyAsync() functions each run in their own thread. But, wait, we never started a thread, did we?


Yes! These tasks are carried out by CompletableFuture on a thread acquired from the global ForkJoinPool.commonPool ()


However, you may construct a Thread Pool and provide it to the runAsync() and supplyAsync() methods to allow them to run their jobs in a thread from your thread pool. There are two versions of every method in the CompletableFuture API: one that accepts an Executor as a parameter and one that does not.

Not only this, but CompletableFuture has also the capability to act as Future. But, this comes at a cost of a few policies. Let's see what they are. Future is also implemented by CompletableFuture with the following policies:

Because this class, unlike FutureTask, has no direct control over the computation that causes it to be finished, cancellation is handled as a different type of exceptional fulfillment. completeExceptionally(new CancellationException()) has the same effect as cancel. 

The isCompletedExceptionally() method may be used to see if a CompletableFuture was finished in an unusual way.

Methods get() and get(long, TimeUnit) throw an ExecutionException with the same reason as the corresponding CompletionException in the case of exceptional completion with a CompletionException.

Other Java Concurrency Articles you may like
  • The Java Developer RoadMap (roadmap)
  • 10 Java Multithreading and Concurrency Best Practices (article)
  • Difference between atomic, volatile, and synchronized (answer)
  • Top 50 Multithreading and Concurrency Questions in Java (questions)
  • Top 5 Books to Master Concurrency in Java (books)
  • Difference between CyclicBarrier and CountDownLatch in Java? (answer)
  • How to avoid deadlock in Java? (answer)
  • What is happens-before in Java concurrency? (answer)
  • Understanding the flow of data and code in Java program (answer)
  • Is Java Concurrency in Practice still valid (answer)
  • How to do inter-thread communication in Java using wait-notify? (answer)
  • 5 Courses to Learn Java Multithreading in-depth (courses)
  • 10 Advanced books for Experienced Programmers (books)
  • 50+ Thread Interview Questions for Beginners (questions)
  • Top 5 skills to Crack Coding interviews (article)
  • 10 Advanced Core Java Courses for Experienced Programmers (courses)

Hope you guys enjoyed the article and learned something new about java. Do try hands-on for CompletableFuture and make sure to complete the Future tasks too :p

Till then, happy Future planning!

P.S. - If you are new to Java Multithreading and looking for a free online training course to learn Multithreading and Concurrency basics then I also suggest you check out this free Java Multithreading course on Udemy. It's completely free and all you need is a free Udemy account to join this course. 

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.