util threads thread multiple lock example ejemplo create concurrent accumulators java exception-handling multithreading executor

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:


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