Search code examples
javamultithreadingjava.util.concurrent

What is the additional task that is being executed when using ExecutorService?


I am learning Java Concurrency. So came across this example online for it. I have written the following code. The issue is, even though the tasks are done executing, it looks like there is something additional that is being executed. So how do I find out what is being executed?

package com.test.executors;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import java.util.logging.Logger;

class MyObject {
    private Integer number;
    private Integer result;

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public Integer getResult() {
        return result;
    }

    public void setResult(Integer result) {
        this.result = result;
    }
}

class FactorialCalculator implements Callable<MyObject> {

    private Integer number;

    public FactorialCalculator(Integer number) {
        this.number = number;
    }

    @Override
    public MyObject call() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " started...");
        MyObject object = new MyObject();
        object.setNumber(number);
        int result = 1;
        if (0 == number || 1 == number) {
            result = 1;
        } else {
            for (int i = 2; i <= number; i++) {
                result *= i;
                TimeUnit.SECONDS.sleep(1);
            }
        }
        object.setResult(result);
        System.out.println(Thread.currentThread().getName() + " done...");
        return object;
    }
}

public class ExecutorMain1 {

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(3);
        List<Future<MyObject>> results = new ArrayList<>();
        Random random = new Random();
        System.out.println("Starting Services...");
        for (int i = 0; i < 5; i++) {
            Integer number = random.nextInt(10);
            Future<MyObject> result = service.submit(new FactorialCalculator(number));
            results.add(result);
        }

        System.out.println("Done submitting tasks...");
        System.out.println("Will display results shortly...");

        for (Future<MyObject> future : results) {

            try {
                System.out.println("Number: " + future.get().getNumber() + "--> Result: " + future.get().getResult() + " Task Status: " + future.isDone());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Exiting main...");
    }
}

The output is -

Starting Services...
Done submitting tasks...
Will display results shortly...
pool-1-thread-2 started...
pool-1-thread-2 done...
pool-1-thread-2 started...
pool-1-thread-2 done...
pool-1-thread-2 started...
pool-1-thread-2 done...
pool-1-thread-1 started...
pool-1-thread-1 done...
Number: 6--> Result: 720 Task Status: true
Number: 5--> Result: 120 Task Status: true
pool-1-thread-3 started...
pool-1-thread-3 done...
Number: 4--> Result: 24 Task Status: true
Number: 0--> Result: 1 Task Status: true
Number: 1--> Result: 1 Task Status: true
Exiting main...

After Exiting main..., the program doesn't exit yet. It is blocking on something. The 5 tasks that are submitted are done as well. So what is being executed? How do I find that out?


Solution

  • JVM will not exit while there are non-daemon threads running. And your ExecutorService creates non-daemon worker threads. So to allow JVM to terminate you need to shutdown executor service. By calling either shutdown() or shutdownNow() since all your tasks already finished.