How to shutdown an ExecutorService?

前端 未结 2 1975
梦毁少年i
梦毁少年i 2020-11-27 02:52

Whenever I call shutdownNow() or shutdown() it doesn\'t shut down. I read of a few threads where it said that shutting down is not guaranteed - can

相关标签:
2条回答
  • 2020-11-27 03:17

    The best way is what we actually have in the javadoc which is:

    The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks:

    void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            pool.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }
    
    0 讨论(0)
  • 2020-11-27 03:21

    The typical pattern is:

    executorService.shutdownNow();
    executorService.awaitTermination();
    

    When calling shutdownNow, the executor will (generally) try to interrupt the threads that it manages. To make the shutdown graceful, you need to catch the interrupted exception in the threads or check the interrupted status. If you don't your threads will run forever and your executor will never be able to shutdown. This is because the interruption of threads in Java is a collaborative process (i.e. the interrupted code must do something when asked to stop, not the interrupting code).

    For example, the following code prints Exiting normally.... But if you comment out the line if (Thread.currentThread().isInterrupted()) break;, it will print Still waiting... because the threads within the executor are still running.

    public static void main(String args[]) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(new Runnable() {
    
            @Override
            public void run() {
                while (true) {
                    if (Thread.currentThread().isInterrupted()) break;
                }
            }
        });
    
        executor.shutdownNow();
        if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
            System.out.println("Still waiting...");
            System.exit(0);
        }
        System.out.println("Exiting normally...");
    }
    

    Alternatively, it could be written with an InterruptedException like this:

    public static void main(String args[]) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(new Runnable() {
    
            @Override
            public void run() {
                try {
                    while (true) {Thread.sleep(10);}
                } catch (InterruptedException e) {
                    //ok let's get out of here
                }
            }
        });
    
        executor.shutdownNow();
        if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
            System.out.println("Still waiting...");
            System.exit(0);
        }
        System.out.println("Exiting normally...");
    }
    
    0 讨论(0)
提交回复
热议问题