Suggested Pages

Tuesday, July 10, 2012

Callable and Executor (java.util.concurrent)

Callable


Callable interface has a similar behaviour of Runnable interface except for the fact that Callable has a generic method public T call(); with a return type.
You can imagine Callable interface as a task to be executed, so when you have to choose tasks and their responsibilities, you are choosing what an instance of Callable should do.

In this example we'll see a program that counts the pair numbers in a List of Integer.
To perform a quick search I have divided the list into two sublists and I assigned two tasks to search the former the head and the latter the tail of the list. Each task returns a sub-total of the count so then we have to sum these sub-totals and print the result.
It's not a good example of concurrency but it's only a way to talk about some features of java.util.concurrent package.

ExecutorService


In this example, I make use of the interface ExecutorService that provides methods to manage the start and the termination of each task.
ExecutorService permits to return for each task (Callable) a Future object that represents a pending result of a specific Callable instance.
I put each instance of Future in a list and then I ask the result to each instance of Future using get() method.

When all the instances of Future in that list return a value, I will use these values to obtain the total count.
You have to notice that ExecutorService is obtained with a static method called Executors.newFixedThreadPool(int numThread) whose numThread value represents the max number of threads to be used by the submitted tasks or Callable instances.

It's important to notice the difference between threads and tasks. The number of threads is not directly linked to the number of tasks: the number of threads is a choice that has different reasons from the number of task which is instead linked to the specific problem you are going to resolve.

MyPairCallable.java

import java.util.List;
import java.util.concurrent.Callable;

public class MyPairCallable implements Callable<Integer> {

 private int count = 0;

 private List<Integer> list;

 public MyPairCallable(List<Integer> list) {
  this.list = list;
 }

 public Integer call() throws Exception {
  for (Integer i : list) {
   if (i % 2 == 0) {
    count++;
   }
  }
  return count;
 }

}
This method returns an Integer which is subtotal of the count of the pair number in the original list.

Main.java

...

public class Main {

 public static void main(String[] args) {

  List<Integer> list = new LinkedList<Integer>();
  for (int i = 0; i < 1000; i++) {
   //int d = (int)(Math.random()*100);
   list.add(i);
  }
  System.out.println(list.size());
  List<Integer> subListFirst = list.subList(0, list.size()/2);
  List<Integer> subListSecond = list.subList(list.size()/2, list.size());
  System.out.println(subListFirst.size());
  System.out.println(subListSecond.size());
  
  ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2);
  
  List<Future<Integer>> futures=new LinkedList<Future<Integer>>();
  futures.add(newFixedThreadPool.submit(new MyPairCallable(subListFirst)));
  futures.add(newFixedThreadPool.submit(new MyPairCallable(subListSecond)));
  int count=0;
  for(Future<Integer>future:futures){
   try {
    count=count+future.get();
   } catch (InterruptedException e) {
    e.printStackTrace();
   } catch (ExecutionException e) {
    e.printStackTrace();
   }
  }
  newFixedThreadPool.shutdown();
  System.out.println(count);
 }
}

No comments :

Post a Comment

Suggested Pages