Java: ведение журнала исключений FutureTask

У меня есть приложение, которое регулярно отправляет задачи для выполнения в выделенном потоке. Этими задачами являются FutureTask<V>, а поток - не более чем бесконечный цикл, который выполняет задания, когда они попадают в очередь, переходя в спящий режим, если он пуст.

Иногда мне нужно дождаться результата вычисления, поэтому я вызываю метод get () FutureTask, который также выдаст исключение, если произойдет что-то плохое. Но бывают случаи, когда мне все равно, каков был результат, если он есть, но мне нужно знать (журнал, printStackTrace () или что-то еще ...), произошел ли какой-то сбой во время выполнения задачи.

Есть ли способ добиться этого, не дожидаясь вызова get (), который мне не нужен?

Заранее спасибо!

ОБНОВЛЕНИЕ: вызов get () в потоке runner после выполнения задачи казался единственным способом перехватить исключение, если никто другой не ожидал результата.

Другим решением могло бы стать расширение класса FutureTask для предоставления метода, который через отражение java предоставляет частное поле sync.exception.


person user683887    schedule 06.05.2012    source источник


Ответы (5)


Если я правильно понимаю вашу проблему, есть простое решение. Измените выделенный поток выполнения задач так, чтобы они вызывали Future.get() после выполнения каждой задачи, а также регистрировали и регистрировали ExecutionException (если есть).

Обратите внимание, что вызов get в потоке запуска задачи после выполнения задачи гарантированно не блокирует.

(Обработчики неперехваченных исключений не помогут, потому что любые исключения и ошибки, вызванные run() методом будущего завернутого Runnable will be caught byFutureTask.run () `.)

person Stephen C    schedule 06.05.2012
comment
Я не могу найти этот метод getException () в Future или FutureTask. Я что-то упускаю? Спасибо за Ваш ответ - person user683887; 06.05.2012

Проверьте Thread.UncaughtExceptionHandler

person kofemann    schedule 06.05.2012
comment
не могли бы вы добавить больше информации об этом? Я попытался установить UncaughtExceptionHandler в потоке runner, но ничего не изменилось, так как я думаю, что эти исключения не отключаются, а управляются FutureTask и не отображаются до тех пор, пока не будет вызван метод get (). Спасибо - person user683887; 06.05.2012

Я думаю, вам следует использовать setException, чтобы сообщить об ошибке в вашей задаче. Это заставит get () сообщить об исключении ExecutionException. Смотрите также это:

Как перехватывать исключения в FutureTask

person Jouni Aro    schedule 06.05.2012
comment
я хочу избежать вызова get () ;-) Я иногда отправляю долго выполняющиеся задачи, чтобы сохранить информацию в базе данных ... В этом случае я не хочу, чтобы меня блокировали в ожидании get (), но я бы хотел увидеть возможные исключения, зарегистрированные где-нибудь. Спасибо - person user683887; 06.05.2012
comment
почему бы вам тогда просто не отловить исключения в своей цепочке и не зарегистрировать их? - person Jouni Aro; 06.05.2012
comment
потому что метод run FutureTask просто не генерирует исключения, поэтому, даже если я помещу его в блок try-catch, ничего не будет регистрироваться. - person user683887; 06.05.2012
comment
Но вы можете поймать их в своем Runnable.run (), который вы предоставляете для FutureTask, не так ли? - person Jouni Aro; 06.05.2012
comment
Что ж, да, я мог бы поймать их в своих Callables, но я надеялся, что есть более простой способ справиться с этим, не требуя от меня изменения всех моих предопределенных классов заданий, а также иметь возможность регистрировать их, даже если я забуду добавить блок try-catch для задания. - person user683887; 06.05.2012
comment
Хорошо, я вижу. Если вы проверите ссылку, которую я предоставил, пользователь попытается войти в переопределенное исключение setException. Только согласно последнему ответу, это работает только с Java 7 из-за ошибки Java. - person Jouni Aro; 06.05.2012
comment
Да, я также пытался переопределить setException (), чтобы посмотреть, могут ли там регистрироваться исключения, но безуспешно. К сожалению, я пока не могу перейти на java 7. - person user683887; 06.05.2012

Здесь можно использовать CompletionService . Использование одного из них позволит вам вызвать get() на Future, когда они определенно будут завершены. В качестве альтернативы библиотеки Guava могут добавить слушателя к Future или FutureTask для выполнения когда задача завершена (ListenableFuture и связанные с ним объекты).

person Paul Blessing    schedule 06.05.2012

Вы также можете проверить пример, который я написал для Futuretask

person Chrys    schedule 06.05.2012