Jeann Pierre Jeann Pierre - 1 month ago 15
Java Question

Executor Does Not Return 10 Future Objects

I have an executor service with a Thread Pool of 10 and I expected that I would get 10 print out statements separated by three seconds, but I only receive one print out statement. I passed 10 as the parameter so I was expecting 10 threads to be running. How can I retrieve the 10 future objects?

public class Demo {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);

public static void main (String[] args) throws ExecutionException, InterruptedException {

ArrayList futureObjects = new ArrayList();

Callable<Integer> task = () -> {
try {
TimeUnit.SECONDS.sleep(3);
return 123;
}
catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
};

System.out.println("Before execution of threads");

Future<Integer> future = executor.submit(task);

Integer result = future.get();
futureObjects.add(future.get());

System.out.println("result: " + result);

for(Object futures : futureObjects ){
System.out.println("Futures in ArrayList: " + futures);
}
}

}


The output I get is:

Before execution of threads

result: 123

Futures in ArrayList: 123

Answer

You have actually added only one task & submitted to the Threadpool, because of which one task executed & returned.

You need to submit multiple tasks together (using Option1 or Option2 below) so that you can actually utilize the Threadpool(to keep threads busy).

You can look at the updated version of the code below:

Option(1) : ExecutorService-invokeAll():

private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main (String[] args) throws ExecutionException, InterruptedException {

        ArrayList futureObjects = new ArrayList();

        Callable<Integer> task = () -> {
            try {
                TimeUnit.MILLISECONDS.sleep(100);
                return 123;
            }
            catch (InterruptedException e) {
                throw new IllegalStateException("task interrupted", e);
            }
        };

        List<Callable<Integer>> callables = new ArrayList<>();
        callables.add(task);
        callables.add(task);
        callables.add(task);
        callables.add(task);
        //Add other tasks

        System.out.println("Before execution of threads");

        List<Future<Integer>> futures = executor.invokeAll(callables);

        for(Future future : futures ){
            System.out.println("Futures in ArrayList: " + future.get());
        }
    }

Option(2) : ExecutorService-submit():

private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main (String[] args) throws ExecutionException, InterruptedException {

        ArrayList futureObjects = new ArrayList();

        Callable<Integer> task = () -> {
            try {
                TimeUnit.MILLISECONDS.sleep(100);
                return 123;
            }
            catch (InterruptedException e) {
                throw new IllegalStateException("task interrupted", e);
            }
        };

        List<Callable<Integer>> callables = new ArrayList<>();
        callables.add(task);
        callables.add(task);
        callables.add(task);
        callables.add(task);
        //Add other tasks

        List<Future<Integer>> futures = new ArrayList<>();
        System.out.println("Before execution of threads");

        for(Callable<Integer> callable : callables) {
            futures.add(executor.submit(callable));
        }

        for(Future future : futures ){
            System.out.println("Futures in ArrayList: " + future.get());
        }
    }

You can refer the API here