schedulewithfixeddelay newscheduledthreadpool example ejemplo java concurrency executorservice blockingqueue

java - newscheduledthreadpool - ScheduledExecutorService con retraso variable



scheduledexecutorservice java 8 (5)

Supongamos que tengo una tarea que extrae elementos de un java.util.concurrent.BlockingQueue y los procesa.

public void scheduleTask(int delay, TimeUnit timeUnit) { scheduledExecutorService.scheduleWithFixedDelay(new Task(queue), 0, delay, timeUnit); }

¿Cómo puedo programar / reprogramar la tarea si la frecuencia se puede cambiar dinámicamente?

  • La idea es tomar un flujo de actualizaciones de datos y propagarlos por lotes a una GUI
  • El usuario debe poder variar la frecuencia de las actualizaciones.

¿No debería utilizar scheduleAtFixedRate si está intentando procesar varias tareas de cola con un intervalo específico? scheduleWithFixedDelay solo esperará el retraso especificado y luego ejecutará una tarea de la cola.

En cualquier caso, los métodos de schedule* en un ScheduledExecutorService devolverán una referencia de ScheduledFuture . Si desea cambiar la tasa, puede cancelar el ScheduledFuture y reprogramar la tarea con una tasa diferente.


No creo que puedas cambiar un retraso de tasa fija. Creo que necesita usar schedule() para realizar un disparo único, y programar nuevamente una vez que se haya completado (con un tiempo de espera modificado si es necesario).


Tuve que hacer esto recientemente usando ScheduledFuture y no quise envolver Runnable o algo así. Así es como lo hice:

private ScheduledExecutorService scheduleExecutor; private ScheduledFuture<?> scheduleManager; private Runnable timeTask; public void changeScheduleTime(int timeSeconds){ //change to hourly update if (scheduleManager!= null) { scheduleManager.cancel(true); } scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, timeSeconds, timeSeconds, TimeUnit.SECONDS); } public void someInitMethod() { scheduleExecutor = Executors.newScheduledThreadPool(1); timeTask = new Runnable() { public void run() { //task code here //then check if we need to update task time if(checkBoxHour.isChecked()){ changeScheduleTime(3600); } } }; //instantiate with default time scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, 60, 60, TimeUnit.SECONDS); }


Use schedule(Callable<V>, long, TimeUnit) lugar de scheduleAtFixedRate o scheduleWithFixedDelay . Luego, asegúrese de que su Callable se reprograme a sí mismo o a una nueva instancia Callable en algún momento en el futuro. Por ejemplo:

// Create Callable instance to schedule. Callable<Void> c = new Callable<Void>() { public Void call() { try { // Do work. } finally { // Reschedule in new Callable, typically with a delay based on the result // of this Callable. In this example the Callable is stateless so we // simply reschedule passing a reference to this. service.schedule(this, 5000L, TimeUnit.MILLISECONDS); } return null; } } service.schedule(c);

Este enfoque evita la necesidad de apagar y volver a crear el ScheduledExecutorService .


scheduleWithFixedDelay (...) devuelve un RunnableScheduledFuture. Para reprogramarlo, puede simplemente cancelarlo y reprogramarlo. Para reprogramarlo, puedes simplemente envolver el RunnableScheduledFuture con un nuevo Runnable:

new Runnable() { public void run() { ((RunnableScheduledFuture)future).run(); } };