Вопрос по multithreading, java – Как отключить ExecutorService?

39

Всякий раз, когда я звонюshutdownNow() или жеshutdown() он не выключается. Я читал о нескольких ветках, где говорилось, что выключение не гарантируется - может кто-нибудь предоставить мне хороший способ сделать это?

Пожалуйста, отметьте правильный ответ как принятый gonephishing

Ваш Ответ

2   ответа
80

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

При звонкеshutdownNowисполнитель будет (обычно) пытаться прерывать потоки, которыми он управляет. Чтобы сделать корректное завершение работы, вам нужно перехватить прерванное исключение в потоках или проверить статус прерванного. Если вы этого не сделаете, ваши потоки будут работать вечно, и ваш исполнитель никогда не сможет завершить работу. Это связано с тем, что прерывание потоков в Java является совместным процессом (т.е.interrupted код должен что-то делать, когда его просят остановить, а неinterrupting код).

Например, следующий код печатает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...");
}

Кроме того, это может быть написано с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...");
}
@ Bionix1441 Нет, это не так.shutdownNow делает хотя.
Знаете ли вы, если отключение также начинаетсяThread.interrupt()из Java API не похоже, чтоshutdown прерывает темы?
17

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();
    }
}

Похожие вопросы