Showing posts with label Callable. Show all posts
Showing posts with label Callable. Show all posts

Difference between Runnable and Callable interface in Java?

 

Runnable and Callable interface both are designed to represent task, which can be executed by any thread. Both does same task for the programmer with few difference between each other. In this tutorial we will see about difference between Runnable and Callable interface difference and when we need to use Runnable and Callable interface in our application. 

  • Runnable interface introduced in JDK 1.0, whereas Callable interface introduced in Java 5 release along with other major changes e.g. Generics, Enum, Static imports and variable argument method.
  • Since both are interface when we implement these interface we need to implement run() method from Runnable interface and call() method from Callable interface.
  • run() method didn't not return any value, whereas call() method returns Object where Callable interface is a generic parameterized interface and Type of value is provided at implementation. 
  • Callable interface can throw checked exception because it's call method throws Exception where as run() method has its limitation. 

Basically if our application needs to return any value from executor method then we need to for Callable interface than Runnable interface.

Bu keeping all these differences and usage between Runnalbe and Callable interface programmer need to be in a position to decide which interface he needs to choose for his application. 

As this is one of the important interview question asked in most of the interviews followed by multi-threading question and mostly asked in Banking domain Java interviews. 


Future and Callable in Java

 

In our previous tutorial we have see about Java Thread Pool with Executor Framework and simple example as how its works. By using same Thread pool we will see about Callable interface working in this tutorial. 

Normally we use Runnable interface to execute multi-threading in Java. Suppose if we need to get some output or return value from run() method then we can't use Runnable interface and it won't return any value.  In case if we expect threads to return a computed result then we can use java.util.concurrent.Callable interface. The Callable object allows to return values after completion of each Thread execution. The Callable object uses generics to define the type of object which is returned and we will see simple example below as how its works along with Future.

If we submit a Callable object to an Executor the framework returns an object of type java.util.concurrent.Future. This Future object can be used to check the status of a Callable and to retrieve the result from the Callable. On the Executor you can use the method submit to submit a Callable and to get a future. To retrieve the result of the future use the get() method. 


import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {
 
 private String name;
 
 public MyCallable(String name) {
  this.name = name;
 }
 
 @Override
 public Integer call() throws Exception {
  return name.length();
 } 
}


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 MyCallableTest {

 public static void main(String[] args) {
  
  String names[] = {"John", "David", "Steve", "Jobs", "Bill", "Gates", "Arnold"};
  
  // Thread pool size set as "5"
  ExecutorService executor = Executors.newFixedThreadPool(5);
  List<Future<Integer>> list = new ArrayList<Future<Integer>>();
     for (int i = 0; i < names.length; i++) {
       Callable<Integer> worker = new MyCallable(names[i]);
       Future<Integer> fur = executor.submit(worker);
       list.add(fur);
     }
     
     for (int i = 0; i < names.length; i++) {
      try {
       Future<Integer> future = list.get(i);
       System.out.println("NAME : ("+names[i] + ") - LENGTH : "+future.get());
   } catch (InterruptedException e) {
    e.printStackTrace();
   } catch (ExecutionException e) {
    e.printStackTrace();
   }
     }  
 }
}

OUTPUT:


NAME : (John) - LENGTH : 4
NAME : (David) - LENGTH : 5
NAME : (Steve) - LENGTH : 5
NAME : (Jobs) - LENGTH : 4
NAME : (Bill) - LENGTH : 4
NAME : (Gates) - LENGTH : 5
NAME : (Arnold) - LENGTH : 6