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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

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