Java Callable Future Example

Callable interface was added in Java 5 to achieve some limitation in existing Runnable interface. A Thread created by implementing the Runnable interface cannot returns a result when the thread terminates. As the return type of run() method in Runnable interface is void. To overcome this the Callable interface was introduced in Java where we can return a result when the thread terminates. Method signature that has to be overridden for implementing Callable is as following.

public Object call() throws Exception;

Another difference between the call() and run() method is call() is able to throw an Exception where run() cannot. The Java Callable interface uses Generics, so it can return any type of Object.

The Executor Framework has a submit() method. Using this we can executes callable threads in a Thread Pool. The Thread pool can be obtained as:

ExecutorService executor = Executors.newFixedThreadPool(10);

Then we can submit a task to it. The task is an implementation of Callable interface. Following is an example of Callable implementation.

public class MyCallable implements Callable{
   @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        //return the thread name executing this callable task
        return Thread.currentThread().getName();
    }
}

To submit the Callable implementation in a Thread Pool is like:

Future future = executor.submit(callable);

Java Future : Java Callable tasks return java.util.concurrent.Future objects. Using this Java Future object, we can find out the status of the Callable task and get the returned Object. It provides a get() method that can wait for the Callable task to finish and then return the result. The Future interface also defines a cancel() method to cancel task. As discussed the get() is a blocking call and it blocks until computation is completed. There are also isDone() and isCancelled() methods to find out the current status of an associated Callable task.

Here is a example of Java Callable task , where we have 3 Array of Integer. Our goal is to add all the array elements and Get their SUM. The task is very straight forward. But we will use different callable tasks to add each array. And then collect all the results from each Callable task in corresponding Future Object. Follwoing is our Callable implementation to add each array.

class SumCalculator implements Callable{

  int[] arr;

  public SumCalculator(int[] inArray){
	this.arr = inArray;
  }

  @Override
  public Integer call() throws Exception {
	int sum = 0;
	for(int i : arr){
	  sum += i;
	}
	return sum;
  }
}

Now following is our Main class, we are going to create a ThreadPool of size 3. And creates 3 Callable tasks and collect the result from corresponding Future Object.

package com.tuturself;

import java.util.ArrayList;
import java.util.List;
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;

public class FutureTest {

 public static void main(String[] str) {

  int[] a = { 10, 12, 23, 2 };
  int[] b = { 12, 2, 3, 4 };
  int[] c = { 33, 4, 5, 6 };

  //Get ExecutorService from Executors utility class, thread pool size is 3
  ExecutorService executor = Executors.newFixedThreadPool(3);

  //create a list to hold the Future object associated with Callable
  List<Future<Integer>> list = new ArrayList<>();

  //Create SumCalculator instances
  Callable<Integer> calculator1 = new SumCalculator(a);
  Future<Integer> future1 = executor.submit(calculator1);
  list.add(future1);

  Callable<Integer> calculator2 = new SumCalculator(b);
  Future<Integer> future2 = executor.submit(calculator2);
  list.add(future2);

  Callable<Integer> calculator3 = new SumCalculator(c);
  Future<Integer> future3 = executor.submit(calculator3);
  list.add(future3);

  int sum = 0;
  for(Future<Integer> future : list){
	try {
	  // get the sum from all the Calculator
	  sum += future.get();
	} catch (InterruptedException | ExecutionException e) {
	  e.printStackTrace();
	}
  }
  //shut down the executor service now
  executor.shutdown();
  System.out.println(" The Sum is :" + sum);
 }
}

Once we execute the above program, you will get the following output:

 The Sum is :116

 

core java 12

FOLLOW US ON LinkedIn



Explore Tutu'rself