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
  •  | 
  •  

Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top