Отвечая на ваши вопросы,
1) Причина, по которой вы не видите каких-либо исключений, заключается в том, что FutureTask#setException
, вызываемый в FutureTask#run
, эффективно поглощает его. Чтобы иметь возможность регистрировать исключение, вы должны либо создать новый класс, расширяющий ScheduledThreadPoolExecutor
, и переопределить метод afterExecute
следующим образом:
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
t = e;
}
}
if (t != null) {
t.printStackTrace();
}
}
или напрямую вызвать get
в вернул ScheduledFuture
примерно так:
var executor = Executors.newSingleThreadScheduledExecutor();
var future = executor.scheduleAtFixedRate(new MyRunnable(null), 1, 1, TimeUnit.SECONDS);
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
2) Самый простой способ перезапустить сбойный runnable - это сделать:
while (true) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
Но imho этот подход не самый чистый , Правильное кодирование вашего Runnable#run
метода для обработки исключений было бы лучшим решением.