Как отменить конкретную задачу по таймауту при использовании ThreadPoolExecutor в Java?

Я использую ThreadPoolExecutor в Java для распараллеливания обработки элементов. Обработка каждого элемента - это отдельная задача, которую я помещаю в очередь для обработки исполнителем. К сожалению, некоторые задачи могут занять слишком много времени, и я хочу иметь возможность отменить такие задачи и продолжить выполнение остальных. Я не хочу ждать метода выключения и его тайм-аута (общая обработка занимает несколько дней). Я хочу что-то вроде цикла по выполняемым в данный момент задачам и проверки того, как долго он выполняется, и отменить его, если он превышает предел.


person Denis Savenkov    schedule 16.03.2015    source источник
comment
Вы можете использовать FutureTask<Void>, чтобы обернуть ваш Runnable. У него есть cancel() метод: docs.oracle.com/javase/7/docs/api/java/util/concurrent/   -  person Alex Salauyou    schedule 16.03.2015


Ответы (1)


ThreadPoolExecutor будет возвращать вам объекты Future, когда вы отправляете ему задачи.

Используйте get (long timeout, TimeUnit unit) для ваших фьючерсов, и если вы получите TimeoutException, то вызовите для них cancel.

person lbalazscs    schedule 16.03.2015
comment
Обратите внимание, что если вы вызываете cancel(true), код в вашем Runnable выдаст InterruptedException, когда будет вызван любой метод, который потенциально может вызвать его, например, sleep(). Вы также можете проверить, не прерывается ли ваш поток, вызвав Thread.interrupted(), как описано здесь. - person Giovanni Botta; 16.03.2015
comment
Позвольте мне добавить, что если вы не вызовете Thread.interrupted() или sleep() или что-то еще, ваш код не завершится только потому, что он является частью задачи, которая была отменена. - person Giovanni Botta; 16.03.2015
comment
@GiovanniBotta Я согласен. Я не стал вдаваться в подробности прерывания задачи, потому что это отдельная тема. - person lbalazscs; 16.03.2015