2009-12-19 34 views
6

Tengo esta pregunta:Java: Cronómetro e hilo crea

Tengo un temporizador. Con scheduleAtFixedRate crea una nueva tarea de temporizador. En esa tarea de temporizador hay cierto código, que puede tomar un tiempo para completar. ¿Cómo puedo asegurarme de que el temporizador no creará una nueva tarea cuando la anterior aún no se haya completado?

Gracias

Respuesta

17

Mi respuesta sería no usar Timer, está obsoleto. Desde Java5, Timer ha sido reemplazado por ScheduledExecutorService, que es mucho más flexible y fácil de usar. Obtienes un control más preciso sobre cómo funciona el programador, el tipo de control que no obtienes con Timer.

Crea uno utilizando la clase de fábrica Executors, que tiene varios métodos de fábrica. El que usted debe mirar es newSingleThreadScheduledExecutor, lo que debería hacer exactamente lo que está buscando:

crea un subproceso único ejecutor que se pueden programar los comandos para ejecutar después de un retraso dado, o para ejecutar periódicamente Las tareas se garantizan a se ejecutan secuencialmente, y no más de una tarea estará activada en cualquier momento dado .

Con un ScheduledExecutorService, en lugar de la subclasificación TimerTask, que subclase Runnable directamente, y luego enviar la tarea al ejecutor. Hay varios métodos en el ejecutor, usted necesita escoger cuál es el adecuado para sus necesidades (Lee el javadoc de ScheduledExecutorService con cuidado), pero la esencia es algo como esto:

// initialise the executor 
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 

    while (tasksRemaining) { 
     // create your task 
     Runnable task = ....; 
     // submit it to the executor, using one of the various scheduleXYZ methods 
     executor.schedule(task, delay, unit); 
    } 

    // when everything is finished, shutdown the executor 
    executor.shutdown(); 

Como siempre, leer el javadoc.

+0

Si está obsoleto y ha sido reemplazado, ¿no debería marcarse como @deprecated? –

+0

En mi opinión, sí, debería ser así, pero las reglas de Sun sobre desaprobación son un tanto desconcertantes. Funcionalmente, 'Timer' /' TimerTask' no ofrece nada sobre el marco ejecutor. – skaffman

+0

¿Podría mostrar un pequeño ejemplo del uso de newSingleThreadScheduledExecutor? Soy nuevo en Java, y nunca escuché sobre la clase de ejecutores. Gracias – Andrey

3

El documento para la Timer class

correspondiente a cada objeto Timer es un solo hilo de fondo que es utilizado para ejecutar todas las tareas del temporizador, secuencialmente. Las tareas del temporizador deben completarse rápidamente. Si una tarea de temporizador tarda demasiado tiempo en completarse, "encierra" la ejecución de tareas del temporizador subproceso. Esto puede, a su vez, retrasar la ejecución de las tareas posteriores , que puede "agrupar" y ejecutar en sucesión rápida cuando (y si) la tarea ofensiva finalmente se completa.

sugiere que sólo hay uno subproceso en segundo plano. Entonces creo que este escenario no ocurrirá.

+1

No, aún creará las tareas adicionales cuando la anterior aún no se haya completado, simplemente no se ejecutarán hasta que termine la primera (y todas pueden ejecutarse inmediatamente después, lo que probablemente no sea el comportamiento deseado) . –