Callable and Future interface in Java


Callable Future Java MultithreadingViews 1630

In this tutorial, we will understand Java Callable and Future interfaces and how to use them along with examples. Both these interfaces are part of the java.util.concurrent package. We can use the Callable and Future interfaces to execute concurrent tasks and retrieve a single result after the task execution.

Java Callable interface

The Callable interface in Java has a call() method that executes asynchronous tasks. It returns a result that we can access using the Future interface. In case the task fails, the call() method throws an Exception. The call() method contains the implementation of the actual task. Below is the syntax of the call() method.

public Object call() throws Exception;

Implementing the Callable interface

To override the call() method that contains the task implementation, we need to create a class that overrides the Callable interface. Below is an example of implementing the Callable interface. This class contains the call() method that calculates the square of a number and returns the result.

import java.util.concurrent.Callable;

class Square implements Callable {

  int a = 5;
  @Override
  public Integer call() throws Exception {
    
    return a*a;
  }
  
}

Java Future interface

The Java Future interface helps to retrieve the result that is returned as an outcome of the call() method. In other words, the Future object stores the result of a task. The interface has several methods to perform different operations.

Future interface methods

Get Result: get() method

The get() method of the Java Future interface helps to retrieve the result of the task executed using the call() method. It returns an object of the specific types that represents the result. If we invoke the get() method before the task completion, then it blocks until it obtains the result. In case we pass parameter to the get() method, then it waits for the specified amount of time to obtain the result. When timeout occurs, it throws TimeOutException.

Object response = future.get();

Object response = future.get(2000, TimeUnit.MILLISECONDS);

Cancel task: cancel() method

We can cancel the asynchronous task execution using the cancel() method of the Future interface in Java. If the task is not implemented, then calling the cancel() method will have no effect.

future.cancel();

Verify taks completion: isDone() method

We can check if the asynchronous task execution is complete using the isDone() method.

Boolean bVal = future.isDone();

Verify task cancellation: isCancelled() method

To check if the task is actually canceled, we can use the isCancelled() method.

Boolean bVal = future.isCancelled();

Example: Java Callable Future interface

Below is an example of how to use Callable and Future interface in Java to execute multiple tasks and obtain a result. Here, we generate square of random numbers between 0 and 10. The call() method contains the implementation of calculating a square of a number. Using the FutureTask class, we can create the number of tasks we want to execute and then create a constructor using the Callable instance. Using the

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class Square implements Callable {
  int num;
  Square(int num) {
    this.num = num;
  }
  
  @Override
  public Object call() throws Exception {
    int result = num*num;
    return result;
  }
  
}
public class CallableDemo {

  public static void main(String[] args) throws InterruptedException, ExecutionException {
    FutureTask[] sqvalue = new FutureTask[4];
    
    for(int i=0;i<2;i++) {
      Random value = new Random();
      Integer val = value.nextInt(10);
      Callable c = new Square(val);
      sqvalue[i] = new FutureTask(c);
      
      Thread th = new Thread(sqvalue[i]);
      th.start();
    }
    
    for(int i=0;i<2;i++) {
      System.out.println(sqvalue[i].get());
    }

  }

}
9
64

We can also use the ThreadPool of the ExecutorService to execute multiple tasks as in the below example. The ExecutorService has a submit() method that helps to invoke the call() method of the Callable interface.

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

class Square implements Callable {
  int num;
  Square(int num) {
    this.num = num;
  }
  
  @Override
  public Object call() throws Exception {
    int result = num*num;
    System.out.println("Square of " + num + " is: " + result);
    return result;
  }
  
}
public class CallableDemo {

  public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService exec = Executors.newFixedThreadPool(5);
    List<Future<Integer>> l = new ArrayList<Future<Integer>>();
    Random value = new Random();
    for(int i=0;i<5;i++) {
      Integer val = value.nextInt(10);
      Square s = new Square(val);
      
      Future<Integer> response = exec.submit(s);
      l.add(response);
    }
    
    for(Future<Integer> f : l) {
      try {
        System.out.println("Result from future is: " + f.get());
        System.out.println("Task completed: " + f.isDone());
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }
    exec.shutdown();
  }
}
Square of 8 is: 64
Square of 1 is: 1
Square of 0 is: 0
Square of 9 is: 81
Square of 6 is: 36
Result from future is: 64
Task completed: true
Result from future is: 36
Task completed: true
Result from future is: 1
Task completed: true
Result from future is: 0
Task completed: true
Result from future is: 81
Task completed: true

Callable vs Runnable

Though there are similarities between Callable and Runnable interfaces, below are the few differences between them.

CallableRunnable
The Callable interface has a call() method to execute taskThe Runnable interface has a run() method to execute task
It returns a resultIt does not return any result
Ideally for small task that return resultIdeal for long running concurrent execution
The call() method can throw an exceptionThe run() method cannot throw an exception

Reference

Translate ยป