我有一个要定期运行的运行库。在特定的运行中,我相信可运行对象遇到了空指针,但是控制台上未显示任何异常。运行失败后,它将再也不会运行。我有两个问题:
scheduler = Executors.newScheduledThreadPool(1);
MyRunnable mr = new MyRunnable(this.data);
scheduler.scheduleWithFixedDelay(mr, 0, STATUS_SENDER_PERIOD, TimeUnit.MILLISECONDS);
答案 0 :(得分:1)
回答您的问题,
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)重新运行失败的可运行对象的最简单方法是:
while (true) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
但是恕我直言,这种方法不是最干净的。正确编码Runnable#run
方法以处理异常将是一个更好的解决方案。