ThreadPoolExecutor shutdown API doc verbiage "не ждет"

В документации для ThreadPoolExector # выключение сказано:

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

Что это обозначает?

Потому что я бы понял, что поставленные в очередь задачи, которые были отправлены, могут не завершиться, но это не то, что происходит; см. этот пример кода, который вызывает завершение работы до того, как завершится запуск всех отправленных задач:

package example;

import java.util.concurrent.*;

public class ExecutorTest {

    public static void main(String ... args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int count = i;
            executorService.execute(() -> {
                System.out.println("starting " + count);
                try {
                    Thread.sleep(10000L);
                } catch (InterruptedException e) {
                    System.out.println("interrupted " + count);
                }
                System.out.println("ended " + count);
            });
        }
        executorService.shutdown();         
    }    
}

Какие отпечатки:

C:\>java -cp . example.ExecutorTest
starting 0
starting 2
starting 1
ended 2
ended 0
starting 3
starting 4
ended 1
starting 5
ended 3
ended 5
ended 4
starting 7
starting 6
starting 8
ended 7
ended 6
ended 8
starting 9
ended 9

C:\>

В этом примере кажется довольно очевидным, что отправленные задачи полностью выполняются. Я запустил это на JDK8 с Oracle и IBM JDK и получил тот же результат.

Итак, что пытается сказать эта строка в документации? Или кто-то написал это для shutdownNow и вырезал-и-вставил в документацию для непреднамеренного завершения работы?

@GhostCat: спасибо, но я не могу избавиться от ощущения, что это неубедительный вопрос. Застрял, неправильно прочитав что-то, и не мог пройти мимо. ценю готовность помочь и терпение. :-)

Nathan Hughes 05.10.2018 19:36

@NathanHughes, тем не менее, вопрос хороший, поскольку он ясен, и вы предоставили экспериментальные данные, чтобы подтвердить свои предположения.

Janus Varmarken 05.10.2018 19:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
2
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Полная цитата из javadoc shutdown():

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.

This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

Завершение работы исполнителя предотвращает появление новых задач Отправлено.

Уже отправленные задачи, будь то начал или все еще ожидающие в очередь, завершат выполнение.


Если вы не хотите, чтобы задачи в очереди выполнялись, вызовите shutdownNow():

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. These tasks are drained (removed) from the task queue upon return from this method.

This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. This implementation cancels tasks via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.

Остановлены ли уже запущенные задачи, зависит от задачи, как описано в последнем абзаце.

Конечно, не знаю, почему я запуталась. Благодарю.

Nathan Hughes 05.10.2018 19:30
Ответ принят как подходящий

В документе ThreadPoolExector#shutdown есть еще одно предложение:

This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

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


И если вам нужно заблокировать поток вызывающего абонента, используйте ThreadPoolExector#awaitTermination(long timeout, TimeUnit unit):

Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

хорошо, оба ответа хороши, но это более актуально, если говорить, что вызывающий абонент не блокирует, чего я не получал из этого.

Nathan Hughes 05.10.2018 19:34

Re, «вызывающий поток не ждет ...» Есть более простой способ сказать это: вы можете сказать: «shutdown() возвращается немедленно». Аналогично, «если вам действительно нужно заблокировать поток вызывающего абонента ...» можно упростить до «если вам нужно подождать, пока не будут завершены оставшиеся задачи ...»

besmirched 05.10.2018 20:06

Другие вопросы по теме