Una discussione nel Code Review chat determinato il seguente comportamento da uno ScheduledExecutorService:ScheduledExecutorService e errore non rilevato
un'operazione pianificata per eseguire fallisce con un problema 'serio', ma non c'è nessun rapporto, eccezione o log del problema . In altri contesti, l'applicazione normalmente terminerebbe con un errore. Nel contesto di ScheduledExecutorService, tuttavia, non esiste alcuna "gestione" di eccezione/errore.
In primo luogo, per fabbricare un problema. La seguente classe ha un inizializzatore statico che è garantito per fallire:
public class InitializerFault {
private static final int value = Integer.parseInt("fubar");
@Override
public String toString() {
return "" + value;
}
}
Quando condotta secondo:
public static void main(String[] args) {
System.out.println(new InitializerFault());
}
produce (che è esattamente quello che mi sarei aspettato):
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
Ma, quando eseguito come:
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");
}
Produce solo:
Built thread Thread[TestThread,5,main]
Exiting
Non v'è alcuna menzione di eventuali errori, non per colpa, no discarica, niente. Questo ExceptionInInitializerError ha provocato un complicato processo di debug nella vita reale, in cui il problema era molto difficile da isolare.
due domande:
- è questo un comportamento previsto Java, che gli errori nel Esecutori sono 'ignorati'?
- qual è il modo giusto per gestire questa situazione?
Questo può aiutare [Gestione delle eccezioni in ThreadPools] (http://stackoverflow.com/questions/3875739/exception-handling-in-threadpools/3875968# 3875968) –