Pregunta

Supongamos que tengo una tarea que está tirando de los elementos de un java.util.concurrent.BlockingQueue y tratamiento.

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 tener un flujo de actualizaciones de datos y propagarlas en el lote a una interfaz gráfica de usuario
  • El usuario debe ser capaz de variar la frecuencia de cambios
¿Fue útil?

Solución

No creo que se puede cambiar un retardo de tipo fijo. Creo que es necesario utilizar schedule () para llevar a cabo un one-shot, y el horario de nuevo una vez que se ha completado (con una hora de modificación si se requiere).

Otros consejos

Uso schedule(Callable<V>, long, TimeUnit) en lugar de scheduleAtFixedRate o scheduleWithFixedDelay. A continuación, asegúrese de que su rescatable reprograma sí misma o una nueva instancia rescatable 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 la ScheduledExecutorService.

No deberías estar usando scheduleAtFixedRate si usted está tratando de procesar varias tareas de la cola con un intervalo específico? scheduleWithFixedDelay sólo se esperará a que el retardo especificada y luego ejecutar una tarea de la cola.

En cualquier caso, los métodos schedule* en un ScheduledExecutorService volverán una referencia ScheduledFuture. Si desea cambiar la velocidad, se puede cancelar el ScheduledFuture y volver a programar la tarea con un ritmo diferente.

scheduleWithFixedDelay (...) devuelve un RunnableScheduledFuture. Con el fin de volver a programarlo, que sólo podría cancelar y volver a programarlo. Para volver a programarlo, es posible que sólo envolver el ingenio RunnableScheduledFuture un nuevo Ejecutable:

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

he tenido que hacer esto utilizando recientemente ScheduledFuture y no quería envolver Ejecutable 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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top