简体   繁体   中英

ExecutorService - How to wait for completition of all tasks in non-blocking style

I am using ExecutorService in Java web server application for executing some computational tasks in parallel style and then calling shutdown() with awaitTermination() to wait for all tasks to be done. Whole computation can sometimes take dozens of minutes.

The thing is awaitTermination() method blocks the main thread until timeout elapsed (or interrupted ) but I just want to start the tasks and immediatedly respond to client and after competition of all tasks shutdown the service ( following conventions to always close the thread pool ).

So my question, is there a way how I can be notified when all tasks are done so I could call the shutdown() method? Listener or something..

Thanks!

You are trying to solve a problem that doesn't exist. Consider the documentation of ExecutorService.shutdown() :

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

This method does not wait for previously submitted tasks to complete execution.

In other words, just calling shutdown() does already everything you want

  • It finishes all previously submitted tasks
  • It initiates a shutdown
  • It does not wait

The only obstacle is that you are calling awaitTermination despite the fact that you don't want to wait, which has a trivial solution: don't call awaitTermination .

The confusion arises because in your question you are asking “how I can be notified when all tasks are done so I could call the shutdown() method” but that is in contradiction to what you are actually doing in the code. You are calling awaitTermination after shutDown so you are not waiting in order to initiate the shutdown, but initiating the shutdown first and waiting for its completion then, which is the purpose of awaitTermination , waiting for the completion of the shutdown .


To put it in one sentence, just call shutDown after submission in order to shutdown the service after completion of all submitted jobs and don't call awaitTermination unless you really want to wait for the termination.

Thanks to comment from VGR I solved my problem with creating yet another Thread in which I wrapped my existing code like this:

Thread thread = new Thread(() -> {
    ExecutorService service = Executors.newCachedThreadPool();

    collection.forEach(item -> service.submit(() -> {
            // some computational work
        });

    try {
        service.shutdown()
        service.awaitTermination(2, TimeUnit.HOURS);
    catch (InterruptedException iEx) {
        // handle exception
    }
});

thread.start();

return ResponseToClient();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM