考虑我使用ScheduledExecutorService安排Runnable定期执行,并出现一些类似OutOfMemory的系统错误。它会被默默地吞噬。
scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
throw new OutOfMemoryError(); // Swallowed
}
}, 0, delay, TimeUnit.SECONDS);
这是正常的吗?
为什么不传播到容器?
处理此类错误的正确方法是什么?
谢谢!
答案 0 :(得分:2)
与OutOfMemoryError
的任何子类型一样,Error
无法恢复,它们对您的程序通常是致命的。如果你试着抓住它,你的程序就会崩溃,这并不重要。
但是,如果您的意思是Exception
而不是Error
,那么您有两种选择:
run()
方法中捕获异常。get()
返回的Future()
上的scheduleWithFixedDelay()
。这会将异常传播回提交线程,但它会阻止,直到发生这种情况。答案 1 :(得分:1)
该方法将返回一个ScheduledFuture实例,获取方法(有或没有超时)将抛出ExecutionException,并将OutOfMemoryError作为原因。
答案 2 :(得分:0)
ListenableFuture中的guava课程可能会有用。
使用此功能,您可以创建一个异常处理程序任务,记录错误,然后尝试重新启动失败的任务。
您仍然需要一个休眠线程来监视异常,但是整个过程只需要一个全局异常处理程序线程(而不是每个计划任务都有一个)。
答案 3 :(得分:0)
就个人而言,我会给你的对象提供一种报告异常的机制,而不是期望一个框架来处理它们。想想异常监听器或类似的东西。
对于一个人来说,你几乎无能为力。
这些执行程序在那里执行你的东西不是为了处理你的代码可能存在的所有问题!
答案 4 :(得分:0)
您可以使用VerboseRunnable
中的jcabi-log类来捕获所有异常并记录它们:
import com.jcabi.log.VerboseRunnable;
Runnable runnable = new VerboseRunnable(
Runnable() {
public void run() {
// do business logic, may Exception occurs
}
},
true // it means that all exceptions will be swallowed and logged
);
现在,当任何人调用runnable.run()
时,不会抛出任何异常。相反,它们被吞下并记录(到SLF4J)。