Executors are not running all the threads.

Viewed 5981

I'm new to Java, and I'm trying this. I have method, which I wish to run that method in parallel. I wish there should be 10 threads calling the method and get their results.

I'm using Callable and Executors for that. I'm creating the thread pool as:

 ExecutorService executor = Executors.newFixedThreadPool(10);

and I when I do this:

 executor.invokeAll(taskList);

out of 10 threads, only 1 thread is been taken from the poll. And I get only this printed:

The current thread is pool-1-thread-1

But I wish there should be 10 similar println statements.

Here is the full code:

import java.util.concurrent.Callable;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;

public class Parallel
{
    public static void main(String args[])
    {
        Learning l = new Learning();
        l.message = "1st Object";
        l.testThread();
    }
}

//this class deals with threads
class Learning
{

    public String message;

    public void setMessage(String message)
    {
        this.message = message;
    }

    //contains the code where
    public void testThread()
    {

       //create a callable for each method
       Callable<String> callable1 = new Callable<String>()
       {
          @Override
          public String call() throws Exception
          {
             System.out.println("The current thread is " + Thread.currentThread().getName());
             return method1();
             // return null;
          }
       };


       //add to a list
       List<Callable<String>> taskList = new ArrayList<Callable<String>>();
       taskList.add(callable1);

       //create a pool executor with 10 threads
       ExecutorService executor = Executors.newFixedThreadPool(10);


       try
       {
         List<Future<String>> futureList = executor.invokeAll(taskList);

       }
       catch (InterruptedException ie)
       {
       }
    }

    //put your code here!
    private String method1()
    {
        return Thread.currentThread().getName();
    }
}

Am I missing something here?

4 Answers

Your ExecutorService have capacity to run 10 threads. But You submitted only one thread. Change testThread method to like this.

// contains the code where
public void testThread() {
    // add to a list
    List<Callable<String>> taskList = new ArrayList<Callable<String>>();
    Callable<String> callable1=null;
    for (int i = 0; i < 10; i++) {
        // create a callable for each method
        callable1 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("The current thread is " + Thread.currentThread().getName());
                return method1();
                // return null;
            }
        };
        taskList.add(callable1);
    }

    // create a pool executor with 10 threads
    ExecutorService executor = Executors.newFixedThreadPool(10);

    try {
        List<Future<String>> futureList = executor.invokeAll(taskList);

    } catch (InterruptedException ie) {
    }
}

The taskList has only one callable in it. Add more callables to the list and sleep for sometime in method1() so that all 10 threads in the pool get busy.

import java.util.concurrent.Callable;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;

public class Parallel
{
    public static void main(String args[])
    {
        Learning l = new Learning();
        l.message = "1st Object";
        l.testThread();
    }
}

//this class deals with threads
class Learning
{

    public String message;

    public void setMessage(String message)
    {
        this.message = message;
    }

    //contains the code where
    public void testThread()
    {

       //create a callable for each method
       Callable<String> callable1[] = new Callable[10];

       for(int i=0;i<10;++i){
       callable1[i] =  new Callable<String>(){
          @Override
          public String call() throws Exception
          {
             System.out.println("The current thread is " + Thread.currentThread().getName());
             return method1();
             // return null;
          }
       };
   }


   //add to a list
   List<Callable<String>> taskList = new ArrayList<Callable<String>>();

   for(int i=0;i<10;++i){
       taskList.add(callable1[i]);
   }

   //create a pool executor with 10 threads
   ExecutorService executor = Executors.newFixedThreadPool(10);


   try
   {
     List<Future<String>> futureList = executor.invokeAll(taskList);
     executor.shutdown();

   }
   catch (InterruptedException ie)
   {
   }
}

//put your code here!
private String method1()
{
    return Thread.currentThread().getName();
}
}

Whenever in doubt check the javadoc. If you read the invokeAll method you will find the following

Executes the given tasks, returning a list of Futures holding their status and results when all complete.

So if you provide one task it will complete one task, If you want it complete 10 tasks you need to provide 10 tasks. Also when there are no more tasks to be submitted you can call

executor.shutDown()

This method will close down the service after ensuring that all the submitted task are completed.

the problem is that executor calls a callable or a runnable. In your tasklist (list) you have added only 1 callable type instance and submitted this tasklist to the executor. So executor will only have 1 job to do. Add your more callable to the task list and then submit to executor.

Related