Question

I am new to Java, Can anyone explain me which method invokes the call method in below given code , also help me to understand the code execution path for give code:

import java.util.ArrayList;
import java.util.Date;
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 MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(1000);         
        return Thread.currentThread().getName();
    }

    public static void main(String args[]){
        //Get ExecutorService from Executors utility class, thread pool size is 10
        ExecutorService executor = Executors.newFixedThreadPool(10);            
        List<Future<String>> list = new ArrayList<Future<String>>();            
        Callable<String> callable = new MyCallable();

        for(int i=0; i< 100; i++){              
            Future<String> future = executor.submit(callable);              
            list.add(future);
        }

        for(Future<String> fut : list){
            try {               
                System.out.println(new Date()+ "::"+fut.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }           
        executor.shutdown();
    }
}
Was it helpful?

Solution

The code submits a Callable 100 times to an ExecutorService containing 10 threads and captures the Futures that indicate when each Callable has been run.

ExecutorService executor = Executors.newFixedThreadPool(10);            
List<Future<String>> list = new ArrayList<Future<String>>();            
Callable<String> callable = new MyCallable();

for (int i = 0; i < 100; i++)
{              
  Future<String> future = executor.submit(callable);              
  list.add(future);
}

Once each of the 10 threads are running a Callable the remaining Callables will be queued up and are run as each thread becomes available.

After all the Callables have been added, the next block of code gets the result from each Future, the important thing being that the calling thread will block on the call to Future.get until the Callable finishes, so the results will be printed in the order the Callables were added.

for(Future<String> fut : list)
{
  try 
  {               
    System.out.println(new Date() + "::" + fut.get());
  } 
  catch (InterruptedException | ExecutionException e) 
  {
    e.printStackTrace();
  }
}     

Finally the executor is shutdown to kill the threads it contains.

executor.shutdown();

OTHER TIPS

In this code you are using an Executor and a ThreadPool. executor.submit(callable) makes the the executor put your Callable into a thread in the pool and to start this thread by running the call() method. To understand this code you should read theese three sites:

Callable: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

ThreadPool: http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html

Executor: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html

When executor.sumbit(callable); is called, an asynchronous task starts in parallel of the current thread to call the call() method of the provided Callable. "In parallel" means, here, in one of the 10 threads of the thread pool created by Executors.newFixedThreadPool(10);.

Your current thread (in main()) then keeps going, doing this a hundred times (The Callables are queued if all 10 threads are already busy).

To retrieve the result of each call, you then have to use the Future object that each of the submits gave you, using get(). This fut.get() will wait until the corresponding call() is finished, and return the result of the call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top