2012-01-05 471 views
8
new Timer().scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
     System.out.println("run"); 
     throw new SomeRandomException(); 
    } 
}, 1000, 1000); 

輸出:運行(拋出異常)Java的Timer類:定時器任務停止執行,如果在某一個任務異常被拋出

這裏有一個問題:我需要一個定時器來檢查特定數據庫中的條件(或其他)。它工作正常,但有時數據庫(或別的東西)會返回一些錯誤,引發異常並且定時器崩潰,然後再次執行任何單個定時器任務。是否有一些Timer實現在run()中拋出異常後繼續工作。

我可以

new Timer().scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
     try { 
      System.out.println("run"); 
      throw new SomeRandomException(); 
     } catch (Exception e) { 
      System.out.println("dummy catch"); 
     } 
    } 
}, 1000, 1000); 

但這似乎跛。

其他的替代方法是編寫我自己的Timer類的實現,吞服run方法的異常(這看起來也不對)。

+0

你需要捕捉'Error's以及或者他們默默地殺死你的任務以及。 – 2012-01-05 13:14:28

回答

7

使用ScheduledExecutorService。它扮演着和Timer一樣的角色,但是修復了它的弱點(就像你遇到的那個一樣)。

+0

不幸的是「如果任務的任何執行遇到異常,則後續執行被禁止。」 - 來自http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,long,long,java.util.concurrent.TimeUnit) – fiction 2012-01-05 13:24:03

+1

是的,這個特定的任務將停止運行,但它不會使執行程序崩潰,並且其他任務仍在計劃中。但我同意你仍然必須捕捉可能發生的異常,並且不能導致任務的調度中止。您可能想要創建一個CatchAllRunnable可重用類。 – 2012-01-05 13:35:19

0

使用ExecutorService;您可以處理編譯時和運行異常。

Handling exceptions from Java ExecutorService tasks
How is exception handling done in a Callable

ThreadPoolExecutor.java 

final void runWorker(Worker w) { 
    Thread wt = Thread.currentThread(); 
    Runnable task = w.firstTask; 
    w.firstTask = null; 
    w.unlock(); // allow interrupts 
    boolean completedAbruptly = true; 
    try { 
     while (task != null || (task = getTask()) != null) { 
      w.lock(); 
      // If pool is stopping, ensure thread is interrupted; 
      // if not, ensure thread is not interrupted. This 
      // requires a recheck in second case to deal with 
      // shutdownNow race while clearing interrupt 
      if ((runStateAtLeast(ctl.get(), STOP) || 
       (Thread.interrupted() && 
        runStateAtLeast(ctl.get(), STOP))) && 
       !wt.isInterrupted()) 
       wt.interrupt(); 
      try { 
       beforeExecute(wt, task); 
       Throwable thrown = null; 
       try { 
        task.run(); 
       } catch (RuntimeException x) { 
        thrown = x; throw x; 
       } catch (Error x) { 
        thrown = x; throw x; 
       } catch (Throwable x) { 
        thrown = x; throw new Error(x); 
       } finally { 
        afterExecute(task, thrown); 
       } 
      } finally { 
       task = null; 
       w.completedTasks++; 
       w.unlock(); 
      } 
     } 
     completedAbruptly = false; 
    } finally { 
     processWorkerExit(w, completedAbruptly); 
    } 
} 
相關問題