Как изящно остановить службу исполнителя с помощью подхода с использованием стоп-файла

У меня есть требование, при котором я выполняю несколько потоков ежедневно. Каждый поток выполняет какую-то задачу. Проблема, которую я пытаюсь решить, заключается в том, чтобы корректно завершить службу исполнителя, используя стоп-файл, который передается в качестве параметра.

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

Я смотрел это сообщение: Удаление всех задач в очереди ThreadPoolExecutor

Может кто-нибудь подробнее рассказать об этом?


person nithatech    schedule 19.09.2013    source источник


Ответы (1)


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

Я думаю, что правильный способ остановить ExecutorService - это использовать на нем метод executorservice.shutdownNow();. Это отменит все задания, которые не были запущены, и прервет все запущенные потоки.

Чтобы проверить прерывание, ваши задачи должны делать что-то вроде:

while (!Thread.currentThread().isInterrupted()) {
    ...
}

В любом месте, где вы поймаете InterruptedException, вам нужно убедиться, что вы снова включили флаг прерывания:

try {
    // something that throws InterruptedException
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    // maybe we should quit the thread here
}

Если вы используете сторонние библиотеки, которые могут съесть InterruptedException, тогда вам, возможно, придется использовать executorservice.shutdown(), который отменяет задания, но не прерывает потоки. Затем вы должны использовать какой-то флаг volatile boolean shutdown (или AtomicBoolean) и сделать что-нибудь в своих методах выполнения:

while (!Thread.currentThread().isInterrupted() && !shutdown) {
    ...
}

Кстати, вы упомянули «метод запуска потока». На всякий случай вы должны реализовать Runnable и отправить их в ExecutorService. Вы не должны отправлять Thread экземпляров.

person Gray    schedule 19.09.2013