Подтвердить что ты не робот

Выключение и ожидание, что первый звонок имеет какую-то разницу?

В чем разница между

ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();

и

eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);

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

4b9b3361

Ответ 1

Сначала вы должны позвонить shutdown. В противном случае вы можете ждать очень долгое время, так как awaitTermination фактически не завершает работу вашего исполнителя.

Если вы хотите дождаться завершения задач, а не ждать завершения работы исполнителя, используйте invokeAll.

Ответ 2

Чтение документации всегда помогает:

shutdownNow:

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

Этот метод не ожидает завершения активного выполнения задач. Используйте awaitTermination, чтобы сделать это.

Нет никаких гарантий, кроме попыток изо всех сил прекратить обработку активно выполняемых задач. Эта реализация отменяет задачи через Thread.interrupt(), поэтому любая задача, которая не отвечает на прерывания, может никогда не завершиться

выключение :

Инициирует упорядоченное завершение, при котором выполняются ранее отправленные задачи, но новые задачи не принимаются. Вызов не имеет никакого дополнительного эффекта, если он уже выключен.

Этот метод не ожидает завершения выполнения ранее представленных задач. Используйте awaitTermination чтобы сделать это.

awaitTermination :

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

Ответ 3

shutdown означает, что служба-исполнитель не принимает больше входящих задач.

awaitTermination вызывается после запроса на завершение работы.

Вам нужно сначала закрыть службу, а затем заблокировать и дождаться завершения потоков.

Если вы хотите, чтобы все потоки завершили работу и настаивали на использовании awaiTermination, вам необходимо установить параметр таймаута достаточно большим. Таким образом, вы можете сделать:

eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
    System.err.println("Threads didn't finish in 60000 seconds!");
}

В качестве альтернативы вы можете сделать:

eService.shutdown();
while (!eService.isTerminated()) {

}

Таким образом, вы можете обеспечить завершение работы всех потоков, если они не прерваны неожиданно.

Ответ 4

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

Ответ 5

executorService.execute(runnableTask);  

//executorService.shutdown(); //it will make the executorService stop accepting new tasks
//executorService.shutdownNow(); //tires to destroy the executorService immediately, but it doesn't guarantee that all the running threads will be destroyed at the same time. This method returns list of tasks which are waiting to be processed.
//List<Runnable> notExecutedTasks = executorService.shutdownNow(); //this method returns list of tasks which are waiting to be processed.developer decide what to do with theses tasks?

//one good way to shutdown the executorService is use both of these methods combined with the awaitTermination
executorService.shutdown();
try{
    if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
        executorService.shutdownNow();
    }
}catch (InterruptedException e){
    e.printStackTrace();
}

Ответ 6

Главное отличие

shutdown() -

1. Not block the calling a thread - means a thread who called the shutdown().
2. Excecutor not accepting new task after calling shutdown().

awaitTermination -

1. Block the calling thread. (as join() method do)

Точка замешательства - потому что shutdown() не убивает ранее отправленную задачу, то почему awaitTermination()

shutdown() также не убивает любую задачу, которая была отправлена ранее, означает, что переданные задачи и текущие задачи могут быть продолжены, тогда зачем нужен awaitTermination().

Предположим, что вы можете подождать всего 10 минут, чтобы завершить все отправленные задачи, и после этого хотите вызвать shutdownNow() (---you уже знает, что он делает), а затем использовать awaitTermination() после вызова shutdown ().

И если нет ограничения по времени, то shutdown() в порядке. Нет необходимости в awaitTermination().

Ответ 7

Из Java8 ThreadPool метод awaitTermination:

    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }

Сначала он проверит состояние запуска пула потоков. И если пул потоков не был закрыт (что установило состояние выполнения как прекращенное), метод awaitTermination не будет возвращаться до истечения времени ожидания. Это объясняет, почему ждать долго, если вы ждете сначала, а затем выключите.

Ответ 8

Вам нужно вызвать метод shutdownNow() после того, как произошел вызов метода awaitTermination(). Только тогда вы сможете узнать фактическое использование метода awaitTermination().