Buscando Claridad en Java ScheduledExecutorService y FutureTask
-
19-09-2019 - |
Pregunta
Me estoy empezando a mirar en Futuros y la ScheduledExecutorService en Java, y me pregunto por qué mi rescatable no se está ejecutando en el calendario que he indicado. En este código de ejemplo, la exigible se ejecuta una vez, pero la aplicación no se completa nunca, ni la ejecución de la tarea de nuevo, que es lo que espera que suceda (estoy seguro de que el problema es con mi expectativa).
Runnables funcionan bien; Callables parecen bloquear para siempre, pero no estoy seguro de por qué .... ¿Qué me falta?
Gracias!
public class ExecutorExample {
/**
* @param args
* @throws ExecutionException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
FutureTask<ArrayList<String>> ft1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>(){
@Override
public ArrayList<String> call() {
ArrayList<String> stuff = new ArrayList<String>();
for(int i = 0;i<10;i++){
String thing ="Adding " + i + " to result";
stuff.add(thing);
System.out.println(thing);
}
return stuff;
}});
scheduler.scheduleAtFixedRate(ft1, 0, 1, TimeUnit.SECONDS);
System.out.println(ft1.get());
System.out.println(ft1.isDone());
}
}
Solución
El problema es que se utiliza FutureTask
, y como dice su documentación de la clase, "Una vez que el cálculo se ha completado, el cálculo no puede ser reiniciado o cancelada."
Después de que el método run
de FutureTask
se ha invocado una vez, invocaciones posterior retorno inmediatamente, sin delegar a instancia Callable
de la tarea.
Sólo un Runnable
se puede utilizar como una tarea periódica, y esto no permite pasar de vuelta un resultado. En su lugar, dar la tarea Runnable
una devolución de llamada que puede invocar al final de su método run
, para informar de los resultados de cada ejecución de la tarea de nuevo a los oyentes en otros hilos.