如何关闭ExecutorService?

ros*_*esr 41 java multithreading shutdown executorservice

每当我打电话shutdownNow()shutdown()不关机时.我读到了一些线程,它说不能保证关闭 - 有人能为我提供一个好方法吗?

ass*_*ias 84

典型的模式是:

executorService.shutdownNow();
executorService.awaitTermination();
Run Code Online (Sandbox Code Playgroud)

在调用时shutdownNow,执行程序将(通常)尝试中断它管理的线程.要使关闭正常,您需要捕获线程中的中断异常或检查中断状态.如果你不这样做,你的线程将永远运行,你的执行者永远无法关闭.这是因为Java中的线程中断是一个协作过程(即被中断的代码必须在被要求停止时执行某些操作,而不是中断代码).

例如,以下代码打印Exiting normally....但是如果您注释掉该行if (Thread.currentThread().isInterrupted()) break;,它将打印,Still waiting...因为执行程序中的线程仍在运行.

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...");
}
Run Code Online (Sandbox Code Playgroud)

或者,它可以写成InterruptedException这样的:

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...");
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*tto 20

最好的方法是我们在javadoc中实际拥有的是:

以下方法分两个阶段关闭ExecutorService,首先调用shutdown拒绝传入的任务,然后shutdownNow在必要时调用 以取消任何延迟的任务:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)