2012-04-18 12 views
10

Estoy desarrollando un servicio que supone comenzar cada hora repitiendo exactamente en la hora (1:00 PM, 2:00 PM, 3:00 PM, etc.).Cómo programar la tarea para el inicio de cada hora

He intentado seguir pero tiene un problema: por primera vez tengo que ejecutar el programa exactamente al inicio de la hora y luego este programador lo repetirá.

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
scheduler.scheduleWithFixedDelay(new MyTask(), 0, 1, TimeUnit.HOURS); 

Cualquier sugerencia para repetir mi tarea independientemente de cuándo ejecute el programa?

Saludos, Imran

Respuesta

10

También sugeriría Quartz para esto. Pero se puede hacer que el código anterior se ejecute primero al comienzo de la hora usando el parámetro initialDelay.

Calendar calendar = Calendar.getInstance(); 
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
scheduler.scheduleAtFixedRate(new MyTask(), millisToNextHour(calendar), 60*60*1000, TimeUnit.MILLISECONDS); 



private static long millisToNextHour(Calendar calendar) { 
    int minutes = calendar.get(Calendar.MINUTE); 
    int seconds = calendar.get(Calendar.SECOND); 
    int millis = calendar.get(Calendar.MILLISECOND); 
    int minutesToNextHour = 60 - minutes; 
    int secondsToNextHour = 60 - seconds; 
    int millisToNextHour = 1000 - millis; 
    return minutesToNextHour*60*1000 + secondsToNextHour*1000 + millisToNextHour; 
} 
+1

usaremos scheduleWithFixedDelay o scheduleAtFixedDelay? Creo que usaremos scheduleAtFixedDelay. de lo contrario, agregará tiempo de ejecución en repetición. – ImranRazaKhan

+2

sí. en su caso, debe usar scheduleAtFixedRate. Actualizó la respuesta – krishnakumarp

7

Si usted puede permitirse el uso de una biblioteca externa, entonces Quartz proporciona muy flexible y fácil de usar modos de planificación. Por ejemplo, el modo cron debe ser perfecto para su caso. A continuación un ejemplo sencillo de programar una cierta Job que se ejecutará cada hora:

quartzScheduler.scheduleJob(
    myJob, newTrigger().withIdentity("myJob", "group") 
         .withSchedule(cronSchedule("0 * * * * ?")).build()); 

Tener un vistazo a la tutorial y examples encontrar formulaciones que se adapte a sus gustos. También muestran cómo lidiar con los errores.

1

Si está utilizando el muelle en su servicio, puede utilizar directamente la anotación @Schedule del planificador basado en anotaciones que toma la expresión cron como parámetro o la demora en milisegundos, simplemente agregue esta anotación sobre el método que desea ejecutar y este método será ejecutado. Disfrute ...........

5

El método millisToNextHour en krishnakumarp de answer se puede hacer más compacto y sencillo en Java 8, lo que resultaría en el siguiente código:

public void schedule() { 
    ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); 
    scheduledExecutor.scheduleAtFixedRate(new MyTask(), millisToNextHour(), 60*60*1000, TimeUnit.MILLISECONDS); 
} 

private long millisToNextHour() { 
    LocalDateTime nextHour = LocalDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS); 
    return LocalDateTime.now().until(nextHour, ChronoUnit.MILLIS); 
} 
Cuestiones relacionadas