java - threads - runnable executorservice example
Excepciones no controladas con ejecutores programados de Java (4)
Tengo el siguiente problema y me gustaría saber qué sucede exactamente. Estoy usando el ScheduledExecutorService de Java para ejecutar una tarea cada cinco minutos. Funciona muy bien. Los ejecutores cambiaron por completo la forma en que hago la programación de subprocesos en Java.
Ahora, busqué Java Doc para obtener información sobre cuál sería el comportamiento en caso de que la tarea programada falle con una excepción no controlada, pero no pude encontrar nada.
¿La próxima tarea programada aún se ejecutará? Si hay una excepción no controlada, ¿el ejecutor programado detiene la tarea de programación? ¿Alguien puede señalar información con respecto a este simple problema?
Muchas gracias.
Parece que la API no define ningún mecanismo específico de manejo de excepciones. Es decir, una excepción no detectada simplemente aparece a través de los marcos de subprocesos y, finalmente, se registra en stderr.
Veo que puede explotar las siguientes estrategias de manejo de excepciones:
- definir manejador en la clase de la tarea que los objetos se envían al grupo de subprocesos;
- proporcione su propia implementación de ThreadFactory al grupo de subprocesos que inicializa el controlador predeterminado mediante setUncaughtExceptionHandler () o uncaughtException () de ThreadGroup ;
Si usa scheduleAtFixedRate()
o scheduleAtFixedDelay()
, y su tarea se resuelve con una excepción, esa tarea no se reprogramará. Sin embargo, otras tareas independientes deben continuar ejecutándose según lo esperado. (Ver API Docs ). Si te importa que esto haya sucedido, puedes obtener el ScheduledFuture
que se devuelve y llamar al método get()
. Si la tarea subyacente arroja una excepción, la expulsará del método get()
, envuelta en una ExecutionException
.
El Javadoc de scheduleAtFixedRate
y scheduleWithFixedDelay
dice "Si cualquier ejecución de la tarea encuentra una excepción, las ejecuciones posteriores se suprimen". No creo que sea exactamente claro, pero parece estar diciendo que si su método de run
arroja cualquier tipo de excepción, entonces el programador eliminará efectivamente esa tarea. Cualquier otra tarea que se ejecute a través de ese programador no debería verse afectada. No debería ser difícil probar lo que realmente hace ...
La cancelación de la tarea puede no ser necesariamente algo malo. Si el método de ejecución arroja una RuntimeException
, probablemente tenga un error en alguna parte y el estado del sistema sea desconocido. Pero, como mínimo, aconsejaría capturar RuntimeException
en su método de ejecución y registrar el seguimiento completo de la pila en SEVERE. Es posible que desee volver a lanzar para cancelar la tarea, según las circunstancias. Pero de cualquier forma, necesitarás que el registro tenga la oportunidad de resolver lo que salió mal.
Este hombre tuvo el mismo problema.
http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
Su solución es capturar Exception
dentro del ejecutable y lanzar una RuntimeException
:
try {
theRunnable.run();
} catch (Exception e) {
// LOG IT HERE!!!
System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
e.printStackTrace();
// and re throw it so that the Executor also gets this error so that it can do what it would
// usually do
throw new RuntimeException(e);
}