Необработанные исключения с запланированными исполнителями Java
У меня есть следующая проблема, и я хотел бы знать, что именно происходит. Я использую Java ScheduledExecutorService для запуска задачи каждые пять минут. Он работает очень хорошо. Исполнители полностью изменили способ программирования потоков на Java.
Теперь я просмотрел Java Doc для получения информации о том, каким будет поведение в случае сбоя запланированной задачи с необработанным исключением, но ничего не нашел.
Выполняется ли следующая запланированная задача? Если существует необработанное исключение, запланированный исполнитель прекращает задачу планирования? Может ли кто-нибудь указать на информацию об этой простой проблеме?
Большое спасибо.
Ответы
Ответ 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.
Я вижу, что вы можете использовать следующие стратегии обработки исключений: