我有一个Java applcation,它使用多个线程,使用 ScheduledExecutorService 在给定时间后启动。每个小时一个线程启动,一些工作并正确终止。但有时(例如,当HTTP请求不起作用时),此线程崩溃,执行程序服务不再启动此类线程。然后我必须退出应用程序(使用Ctrl-C)并重新启动它。
崩溃线程是否可能会中断ExecutorService以实例化新线程? 我不想总是检查应用程序是否仍在运行,因为它在我的Raspberry Pi上运行并且应该全天候运行。
也许你可以帮我找到解决问题的方法!
修改:
ExecutorService 也可以在自己的线程上运行。这是线程的启动方式:
@Override
public void run() {
threadFuture = executorService.scheduleAtFixedRate(new IntervalThread(i, p, c, a), 60, 60, TimeUnit.MINUTES);
}
这是每60分钟调用一次的线程:
@Override
public void run() {
try {
// do some HTTP request here
// if an error occurs, catch it and log the error message
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
如果线程(发出HTTP请求)崩溃,则整个 ExecutorService 不再起作用。如果我抓住每个例外情况怎么可能呢?
答案 0 :(得分:2)
您的案例确实有解释,因为ScheduledThreadPoolExecutor
如果任务的任何执行遇到异常,则后续执行将被禁止。
虽然您正在try{}catch(Exception)
块中执行整个任务/工作,但有些情况下,Throwable可能会“逃离”catch
块:
发生了某种错误(例如OutOfMemoryError)。
您的日志记录代码LOGGER.error(e.getMessage());
在记录时抛出了异常。
我建议您进行以下修改以了解发生了什么:
@Override
public void run() {
try {
try {
// do some HTTP request here
// if an error occurs, catch it and log the error message
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
} catch (Throwable t){
t.printStackTrace(); // this would require redirect output like java -jar my.jar >> error_log.txt
// try clean up and exit jvm with System.exit(0);
}