Обнаружив, что FutureTask
, работающий в Executors.newCachedThreadPool()
на Java 1.6 (и из Eclipse), проглатывает исключения в методе Runnable.run()
, я попытался придумать способ отловить их, не добавляя throw / catchко всем моим Runnable
реализациям.
API предлагает, чтобы переопределение FutureTask.setException()
должно помочь в этом:
Заставляет это будущее сообщать об исключении ExecutionException с заданным throwable в качестве причины, если это Будущее уже не было установлено или было отменено.Этот метод вызывается изнутри методом 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
, есть ли для этого какая-то причина?