Java - How to make an ExecutorService running inside another ExecutorService not to shutdown when shutdown is invoked on the outer ExecutorService?

StackOverflow https://stackoverflow.com/questions/23684189

  •  23-07-2023
  •  | 
  •  

Question

I have a Executor service running inside another executor service to send emails. If I call shutdown on the outer executor, it is waiting for the inner executor service to shutdown which is drastically affecting the response time.

private final ExecutorService blastExecutor = Executors.newFixedThreadPool(20);
private final ExecutorService mailExecutor  = Executors.newFixedThreadPool(2);

public void findDealers() {

          blastExecutor.execute(new Runnable() {
                        public void run() {
                            try {
                                identifyDealers();
                            } catch (Exception e) {

                            }
                        }
                    });

        blastExecutor.shutdown();
        try {
            blastExecutor.awaitTermination(30, TimeUnit.MINUTES);

        } catch (InterruptedException e) {

        }
        logger.info("Completed sending request blasts.");
}

public void identifyDealers() {

           mailExecutor.execute(new Runnable() {
                        public void run() {
                            try {
                                sendEmail();
                            } catch (Exception e) {

                            }
                        }
                    });
}

Here, at blastExecutor.shutdown() it invokes shutdown of mailExecutor as well(?)

This is just a sample code and there are lot of business happening inside identifyDealers() method. How can I make sendEmail asynchronous and make blastExecutor.shutdown() not to wait for shutdown of mailExecutor?

Was it helpful?

Solution

Your assumption seems to be wrong, shutdown() should only act on the outer executor. It does not shut down any other executors.

Here's a small example based on your code:

ExecutorService e1 = Executors.newFixedThreadPool(20);
final ExecutorService e2 = Executors.newFixedThreadPool(2);

e1.execute(new Runnable() {
    public void run() {
        System.out.println("e1 started");

        e2.execute(new Runnable() {
            public void run() {
                System.out.println("e2 started");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
                System.out.println("e2 completed");
            }
        });

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

    }
});

e1.shutdown();
System.out.println("e1 shut down signal send");

e1.awaitTermination(30, TimeUnit.MINUTES);
System.out.println("e1 terminated");

e2.awaitTermination(30, TimeUnit.MINUTES);
System.out.println("e2 terminated");

The application won't terminate, it blocks on e2.awaitTermination and in the output it also shows that e2 never got a shut down signal:

e1 started
e1 shut down signal send
e2 started
e1 terminated
e2 completed

If mailExecutor really does shut down, I think there is something else going on that is not shown in your code. As the basic structure of your code looks now, you are running a single task and immediately shut down the executer, which could mean you may don't even need the blastExecutor.

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