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

uscita: run (viene generata un'eccezione)Java Timer classe: compiti timer della sosta da eseguire se in uno dei compiti viene generata un'eccezione

qui è il problema: ho bisogno di un compito timer per verificare la presenza di specifiche condizioni nel database (o qualcos'altro). Ha funzionato bene, ma a volte il database (o qualcos'altro) restituisce alcuni errori, viene lanciata un'eccezione e il timer si arresta in modo anomalo e quindi non viene eseguita nuovamente alcuna attività del timer. Esiste un'implementazione di un timer che continua a funzionare dopo che l'eccezione è stata generata in run().

posso

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); 

ma questo sembra zoppo.

Un'altra alternativa è scrivere la mia implementazione della classe Timer, ingoiando le eccezioni del metodo run (che sembra non essere corretto).

+0

È necessario prendere 'Error's come bene o silenziosamente uccidere il vostro compito pure. –

risposta

7

Utilizzare uno ScheduledExecutorService. Ha lo stesso ruolo di Timer, ma corregge i suoi punti deboli (come quello che stai incontrando).

+0

Sfortunatamente "Se una qualsiasi esecuzione dell'attività riscontra un'eccezione, le esecuzioni successive vengono soppresse." - da http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit) – fiction

+1

Sì, questa particolare attività smetterà di funzionare, ma non farà arrestare l'esecutore e altre attività saranno ancora pianificate. Ma sono d'accordo sul fatto che devi ancora rilevare eventuali eccezioni che potrebbero accadere e non deve causare l'interruzione della pianificazione dell'attività. Potresti voler creare una classe riutilizzabile CatchAllRunnable. –

0

Utilizzando ExecutorService; è possibile gestire sia la compilazione che l'esecuzione di eccezioni.

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); 
    } 
}