Callable and Runnable….. & Need of Completable Future(part-3)

Chinmay Venkata Sabbam
art of coding
Published in
6 min readDec 10, 2019

Before Reading this blog please go through for better understanding

Why Callable …..?

In previous blogs…. In all examples tasks execute through thread-pool does not return any results, that means all examples implemented with the Runnable interface. if tasks execute through thread pool has some outcome, then ….. we need to implement through callable interface.

Runnable interface is a functional interface, which implements the run method. run() method is a void method. execute() method of the Executor Thread-pool took Runnable interface as parameter.

Callable is also a functional interface as similar as the Runnable interface. which implements call() method. it has a return type. it is not an void method. submit() method of the ExecutorThread-pool took Callable interface as parameter. it will give results as Future

submit() method accepts both Runnable and callable as parameters. but it returns Future when we send callable interface as a parameter.

Future

Future is a Object which creates at the time of the task executing, when each task is completed, result is stored in the Future Object. if you use the method future.get() then it is wait until the task get completed and then it will give result.

we can understand callable and future through below example

Example with callable and Future
Callable and Future execution in fixed thread pool
  1. In above example Each task implements the callable interface and it returns the String. there are 10 tasks and 3 threads executes these 10 tasks asynchronously with the Fixed thread Pool Executor.
  2. when the task-1 executes then there is no string in Future Object. if task executed completely then only string is stored in Future Object.
  3. when we perform a get() operation on the Future Object of a particular task, main thread is blocked and it will wait until the task is completed even though if task is not completed at that time and it gives result while we iterating all Future Objects of these 10 tasks.

Note : Try not to use Future.get() method in real Time, if task took more time, main thread will block and it may lead to dead-lock condition.Always use with get() method with specific time period

future.get(long, TimeUnit);

Advantage of Callable

List<Future<?>> futures = executorPool.invokeAll(List<class extends Callable>);
Future future = executorPool.invokeAny(class extends Callable);

This invokeAll() and invokeAny() could have an added advantage to callable then Runnable.

use-case : if you have more number of tasks if you send all the tasks to the Non-blocking queue, it may lead to memory issues in real time.

if you took all rows from the big data like Cassandra and we need to perform the tasks on executor thread pool directly. it will lead to memory issues in real time.At that time invokeall() method saves us from the memory issues

Real time advantages with callable interface
output image of the above program

if you observe the above program, it consists of 95 tasks and thread pool of 3 threads. here we are insisting only 10 tasks will submitted to the thread pool at a time. it executes in this manner

1–10 tasks — — — — 10 tasks submitted — — — — — — — — — 3 threads

10–20 tasks — — — —10 tasks submitted — — — — — — — — 3 threads

20–30 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

30–40 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

40–50 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

50–60 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

60–70 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

70–80 tasks — — — — 10 tasks submitted — — — — — — — — 3 threads

80–90 tasks — — 10 tasks submitted(seen in output picture) — 3 threads

90–95 tasks — — — — 5 tasks submitted — — — — — — — — 3 threads

Comparison Between Runnable and callable interfaces

Runnable

  1. it is a interface with single method . so we can apply a lambda expressions
  2. it can be implemented through both execute() and submit() methods of the executor thread pool.
  3. it can be implemented in a Thread constructor
Thread th = new Thread(Runnable runnable);

4. it does not have support for invokeAll() and invokeAny() methods of the executor thread Pool

5. it does not return any output and it does not throw any checked exceptions (exceptions which are handled during compile time)

6. Runnable interface is introduced in Java from JDK 1.0

Callable

  1. it is a interface with single method . so we can apply a lambda expressions
  2. it can be implemented through only submit() method of the executor thread pool.
  3. it cannot be implemented in a Thread constructor

4. it have support for invokeAll() and invokeAny() methods of the executor thread Pool

5. it will return output through Future Object which acts like holder and it throws checked exceptions (exceptions which are handled during compile time)

6. Callable interface is introduced in Java from JDK 1.5

Is Java does Really Supports an Asynchronous Programming ?

No until java 1.7 , when Java 8 supports an Asynchronous programming when it is flexible for functional style of programming by Implementing Completable Future which is similar semantics as Promises in Java Script.

In what case completable Future Required……….

lets focus on below program

multiple methods in executor thread pool
Output of the above program

In the above program two methods getting an order and paying an order will independent of each-other and it executed asynchronously without any blocking of the main thread.

Need of Completable Future:

Let us consider we have three methods, which are dependent on each other

  1. orderBooking (CPU intensive)
  2. orderConformation (IO intensive)
  3. payment conformation (CPU intensive)

you need to execute all these methods as dependent for each client ,but client to client as an Independent flow as shown as below diagram without dependent of main thread.

Need to execute in this way

Program Generally we write ….

Multiple methods with dependency example
way of running above program

Above program runs for 100 clients

Initially it runs orderBooking for 100 clients

then it runs orderConformation for 100 clients

then it runs paymentConformation for 100 clients

which is equal to sequential execution and it is completely in correct. to solve this use case completable futures are used. we will discuss in further posts

--

--