2014-12-03 58 views
12

Code Review chat讨论确定从ScheduledExecutorService的以下行为:ScheduledExecutorService的和未捕获的错误

计划运行的任务失败了“严重”的问题,但没有报告,异常或问题的日志。在其他情况下,应用程序通常会以错误结束。但是,在ScheduledExecutorService的上下文中,根本没有Exception/Error'handling'。

首先,制造一个问题。下面类有注定要失败,静态初始化:

public class InitializerFault { 

    private static final int value = Integer.parseInt("fubar"); 

    @Override 
    public String toString() { 
     return "" + value; 
    } 

} 

当运行为:

public static void main(String[] args) { 
    System.out.println(new InitializerFault()); 
} 

它产生(这正是我所期望的):

Exception in thread "main" java.lang.ExceptionInInitializerError 
    at SimpleHandler.main(SimpleHandler.java:5) 
Caused by: java.lang.NumberFormatException: For input string: "fubar" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Integer.parseInt(Integer.java:580) 
    at java.lang.Integer.parseInt(Integer.java:615) 
    at InitializerFault.<clinit>(InitializerFault.java:4) 
    ... 1 more 

但是,运行时为:

private static final Thread buildThread(Runnable r) { 
    Thread t = new Thread(r, "TestThread"); 
    t.setDaemon(true); 
    System.out.println("Built thread " + t); 
    return t; 
} 
public static void main(String[] args) throws InterruptedException { 
    // use a thread factory to create daemon threads ... can be non-daemon as well. 
    ScheduledExecutorService ses = Executors.newScheduledThreadPool(
      2, (r) -> buildThread(r)); 
    ses.scheduleAtFixedRate(
      () -> {System.out.println(new InitializerFault());}, 
      500, 1000, TimeUnit.MILLISECONDS); 
    Thread.sleep(3000); 
    System.out.println("Exiting"); 
} 

它产生的只是:

Built thread Thread[TestThread,5,main] 
Exiting 

没有任何错误,没有故障,没有转储,没有提及。此ExceptionInInitializerError导致了一个复杂的现实生活调试过程,其中的问题很难隔离。

两个问题:

  1. 是这样期望的Java行为,即在执行人的错误被 '忽略'?
  2. 什么是正确的方式来处理这种情况?
+0

这可以帮助你[在ThreadPools中的异常处理](http://stackoverflow.com/questions/3875739/exception-handling-in-threadpools/3875968# 3875968) – 2014-12-03 16:17:41

回答

4

ScheduledExecutorService.scheduleAtFixedRate返回ScheduledFuture。如果我们调用ScheduledFuture.get(),线程将阻塞并等待周期性任务完成,这可能会在任务取消时发生,或者如果任务抛出异常。在后一种情况下get()会抛出java.util.concurrent.ExecutionException包装原始异常

+4

对,我现在已经尝试过了,当然(当然)你是对的,它的确如此。虽然你的答案是正确的,但这是一个丑陋的解决方案....真正的任务本身使用try/catch块定期执行异常处理,但不会捕获错误...此外,在主线程(或非执行程序线程)不是很实用。如果我想在那里阻止,我不会使用延迟。这不是你的错,但你建议的解决方案是'丑陋'。 – rolfl 2014-12-03 14:22:36

相关问题