После обнаружения того, что FutureTask работает в Executors.newCachedThreadPool() на Java 1.6 (и из Eclipse), проглатывает исключения в методе Runnable.run(), я попытался найти способ поймать их без добавления throw/catch для всех моих реализаций Runnable.
API предполагает, что переопределение FutureTask.setException() должно помочь в этом:
Заставляет это будущее сообщать об исключении Execution с заданным броском в качестве причины, если это будущее уже не было установлено или отменено. Этот метод вызывается внутренним методом run при сбое вычисления.
Однако этот метод, похоже, не вызван (работа с отладчиком показывает, что исключение попадает на FutureTask, но setException не вызывается). Я написал следующую программу для воспроизведения моей проблемы:
public class RunTest {
public static void main(String[] args) {
MyFutureTask t = new MyFutureTask(new Runnable() {
@Override
public void run() {
throw new RuntimeException("Unchecked exception");
}
});
ExecutorService service = Executors.newCachedThreadPool();
service.submit(t);
}
}
public class MyFutureTask extends FutureTask<Object> {
public MyFutureTask(Runnable r) {
super(r, null);
}
@Override
protected void setException(Throwable t) {
super.setException(t);
System.out.println("Exception: " + t);
}
}
Мой главный вопрос: как я могу поймать Исключения, брошенные в FutureTask? Почему вызов setException не вызван?
Также мне хотелось бы знать, почему механизм Thread.UncaughtExceptionHandler не используется FutureTask, есть ли причина для этого?