2009-01-03 16 views
221

Tengo el código donde programo una tarea usando java.util.timer. Estaba mirando alrededor y vi que ExecutorService puede hacer lo mismo. Entonces, esta pregunta aquí, ¿ha usado Timer y ExecutorService para programar tareas? ¿Cuál es el beneficio de que uno use sobre otro?Java Timer vs ExecutorService?

También quería comprobar si alguien había utilizado la clase Timer y se encontró con algún problema que el ExecutorService resolvió para ellos.

+1

Y si necesita algo aún más featurefull, echa un vistazo a [cuarzo] (http://www.quartz-scheduler.org/). Le brinda mucho más control del trabajo, incluida la programación cron, la programación consciente del clúster, el control individualizado de los trabajos (conceptos como uno por vez, dependencias, etc.). --Tim – Tim

Respuesta

259

Según Java Concurrency in Practice:

  • Timer pueden ser sensibles a los cambios en el reloj del sistema, ScheduledThreadPoolExecutor no lo es.
  • Timer tiene solo un hilo de ejecución, por lo que una tarea de larga duración puede retrasar otras tareas. ScheduledThreadPoolExecutor se puede configurar con cualquier cantidad de subprocesos. Además, tiene control total sobre los hilos creados, si lo desea (proporcionando ThreadFactory).
  • excepciones de tiempo de ejecución tirado en TimerTask matan que un hilo, con lo que Timer :-(muerto ... es decir, las tareas programadas no se ejecutará más. ScheduledThreadExecutor no sólo las capturas excepciones de tiempo de ejecución, sino que le permite manejarlos si lo desea (por razones imperiosas afterExecute método de ThreadPoolExecutor). tarea que arrojó excepción será cancelada, pero otras tareas seguirá funcionando.

Si puede utilizar en lugar de ScheduledThreadExecutorTimer, que lo hagan.

Una cosa más ... mientras que ScheduledThreadExecutor no está disponible en La biblioteca Java 1.4, hay un Backport of JSR 166 (java.util.concurrent) to Java 1.2, 1.3, 1.4, que tiene la clase ScheduledThreadExecutor.

20

ExecutorService es más nuevo y más general. Un temporizador es solo un hilo que ejecuta periódicamente cosas que ha programado para él.

Un ExecutorService puede haber un grupo de subprocesos, o incluso hacia fuera a través de otros sistemas en un grupo y hacer las cosas de una sola vez como la ejecución por lotes, etc ...

Basta con mirar lo que cada uno ofrece a decidir.

56

Si está disponible para usted, entonces es difícil pensar en un motivo no en para usar el marco de ejecución de Java 5. Calling:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 

le dará una ScheduledExecutorService con funcionalidad similar a Timer (es decir, será de un solo roscada) pero cuyo acceso puede ser ligeramente más escalable (bajo el capó, que utiliza estructuras concurrentes en lugar de la sincronización completa como con la clase Timer).El uso de un ScheduledExecutorService también le da ventajas tales como:

  • se puede personalizar si es necesario (ver el newScheduledThreadPoolExecutor() o la clase ScheduledThreadPoolExecutor)
  • El 'uno de' ejecuciones pueden devolver resultados

sobre las únicas razones para pegarse a Timer que puedo pensar son:

  • está disponible pre Java 5
  • Se proporciona una clase similar en J2ME, lo que podría hacer la portabilidad de su aplicación más fácil (pero no sería terriblemente difícil añadir una capa común de la abstracción en este caso)
+0

Otra razón para usar 'TimerTask' puede ser la disponibilidad del método' scheduledExecutionTime() 'que no parece tener ningún equivalente en' ScheduledExecutorService'. –

+3

Otra nota: estoy escribiendo este comentario en 2k17, no hay más J2ME. ya está muerto. – msangel

+1

Java Timer-class es horrible. – JohnyTex

5

Mi razón para preferir a veces temporizador sobre Executors.newSingleThreadScheduledExecutor() es que obtengo un código mucho más limpio cuando necesito el temporizador para ejecutar en los hilos daemon.

comparar

private final ThreadFactory threadFactory = new ThreadFactory() { 
    public Thread newThread(Runnable r) { 
     Thread t = new Thread(r); 
     t.setDaemon(true); 
     return t; 
    } 
}; 
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

con

private final Timer timer = new Timer(true); 

hago esto cuando yo no necesito la robustez de un ExecutorService.

2

Desde la página de documentación Oralce en ScheduledThreadPoolExecutor

Un ThreadPoolExecutor que, además, puede comandos de programación para ejecutar después de un retraso dado, o para ejecutar periódicamente. Esta clase es preferible a Temporizador cuando se necesitan múltiples subprocesos de trabajo, o cuando se requieren flexibilidad o capacidades adicionales de ThreadPoolExecutor (que se extiende esta clase).

ExecutorService/ThreadPoolExecutor o ScheduledThreadPoolExecutor es una opción obvia cuando tiene múltiples hilos de trabajo.

Pros de ExecutorService sobre Timer

  1. Timer no puede tomar ventaja de núcleos de CPU disponibles a diferencia ExecutorService especialmente con el uso de múltiples tareas falvours de ExecutorService como ForkJoinPool
  2. ExecutorService proporciona API colloborative si necesita COORDINACIÓN entre multple Tareas. Suponga que debe enviar N número de tareas de trabajador y esperar a que se completen todas. Puede lograrlo fácilmente con invokeAll API. Si desea lograr lo mismo con múltiples tareas Timer, no sería simple.
  3. ThreadPoolExecutor proporciona una mejor API para la gestión del ciclo de vida del hilo.

    Agrupaciones de hebras abordan dos problemas diferentes: por lo general ofrecen un mejor rendimiento al ejecutar un gran número de tareas asíncronas, debido a la reducción de gastos generales invocación por cada tarea, y proporcionan un medio de delimitación y gestión de los recursos, incluidos los hilos, consumido al ejecutar una colección de tareas. Cada ThreadPoolExecutor también mantiene algunas estadísticas básicas, tales como el número de tareas completadas

    algunas ventajas:

    a. Puede crear/administrar/controlar el ciclo de vida de los subprocesos & optimizar los costos generales de costos de creación de subprocesos

    b. Puede controlar el procesamiento de tareas (Work Stealing, ForkJoinPool, invokeAll) etc.

    c. Puede controlar el progreso y el estado de los hilos

    d. Proporciona una mejor excepción mecanismo de manejo de