Необработанные исключения с запланированными исполнителями Java - PullRequest
29 голосов
/ 02 ноября 2009

У меня есть следующая проблема, и я хотел бы знать, что именно происходит. Я использую Java ScheduledExecutorService для запуска задачи каждые пять минут. Это работает очень хорошо. Исполнители полностью изменили способ программирования потоков в Java.

Теперь я просмотрел Java Doc для получения информации о поведении в случае сбоя запланированного задания с необработанным исключением, но не смог ничего найти.

Следующая запланированная задача все еще будет выполняться? Если есть необработанное исключение, запланированный исполнитель останавливает задачу планирования? Кто-нибудь может указать на информацию относительно этой простой проблемы?

Большое спасибо.

Ответы [ 4 ]

29 голосов
/ 02 ноября 2009

Javadoc как scheduleAtFixedRate, так и scheduleWithFixedDelay говорит: «Если какое-либо выполнение задачи встречает исключение, последующие выполнения подавляются». Я не нахожу это совершенно кристально чистым, но, похоже, говорится, что если ваш метод run выдает какие-либо исключения, то планировщик будет эффективно отбрасывать эту задачу. Любые другие задачи, выполняемые через этот планировщик, не должны быть затронуты. Не должно быть трудно проверить, что он на самом деле делает ...

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

12 голосов
/ 02 ноября 2009

Если вы используете scheduleAtFixedRate() или scheduleAtFixedDelay(), и ваша задача выручает за исключением, эта задача не будет перенесена. Однако другие независимые задачи должны продолжать выполняться, как ожидается. (См. Документы API ). Если вас волнует, что это произошло, вы можете взять ScheduledFuture, который возвращается, и вызвать метод get(). Если основная задача создает исключение, вы получите его из метода get(), заключенного в ExecutionException.

3 голосов
/ 05 марта 2014

У этого человека была такая же проблема.

http://code.nomad -labs.com / 2011/12 / 09 / мать-Ф.К.-The-scheduledexecutorservice /

Его решение состоит в том, чтобы поймать Exception внутри работоспособного и перебросить RuntimeException:

try {
       theRunnable.run();
    } catch (Exception e) {
       // LOG IT HERE!!!
       System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
       e.printStackTrace();

       // and re throw it so that the Executor also gets this error so that it can do what it would
       // usually do
       throw new RuntimeException(e);
}
0 голосов
/ 02 ноября 2009

Похоже, что API не определяет какой-либо конкретный механизм обработки исключений. То есть неперехваченное исключение просто выскакивает через фреймы потоков и в итоге записывается в stderr.

Я вижу, что вы можете использовать следующие стратегии обработки исключений:

  • определить обработчик в классе задачи, какие объекты передаются в пул потоков;
  • предоставляет собственную реализацию ThreadFactory в пуле потоков, которая инициализирует обработчик по умолчанию с помощью setUncaughtExceptionHandler () или uncaughtException () ;
...