2014-12-03 25 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

相關問題