2012-01-05 469 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); 
    } 
} 
相关问题