Необработанные исключения с запланированными исполнителями Java

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

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

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

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

4 ответов


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

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


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


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

http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

его решение-поймать Exception внутри runnable и повторно бросить 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);
}

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

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

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