Estoy empezando a buscar Futures y el ScheduledExecutorService en Java, y me pregunto por qué mi Callable no se está ejecutando en el horario que he indicado. En este código de ejemplo, el invocable se ejecuta una vez, pero la aplicación nunca se completa, ni la tarea se ejecuta nuevamente, que es lo que esperaba que sucediera (estoy seguro de que el problema está con mis expectativas).Buscando Clarity en Java ScheduledExecutorService y FutureTask
Runnables funcionan bien; Los Callables parecen bloquear para siempre, pero no estoy seguro de por qué ... ¿Qué me estoy perdiendo?
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());
}
}
No estoy seguro de seguir esto. FutureTask implementa Runnable, y espero que llame al método call() y almacene el resultado. Entonces esperaría que get() bloqueara hasta que se termine el trabajo, o devuelva el resultado en caché inmediatamente. Entonces, ¿el planificador no ejecutaría el FutureTask, lo que daría como resultado que call() y el resultado se guarde en caché para su posterior reunión? –
Sí, pero solo una vez. Cualquier invocación programada después de la primera llamaría a 'ejecutar' en el FutureTask, pero que el método de ejecución "cortocircuitos" sin invocar 'call' en el Callable. Pero el programador no tiene conocimiento de esto y sigue ejecutándose para invocar FutureTask, por lo que el programa no finaliza. – erickson
Tiene perfecto sentido. Estaba tan agachado en los javadocs por los Executors y su tipo y me perdí por completo esa línea obvia en FutureTask. Como una pregunta de seguimiento, si lo que quiero que suceda como resultado de mi tarea es que se actualiza un BlockingQueue, ¿es preferible pasar esa cola a cada ejecutable, o implementar un oyente que viviría fuera del ejecutable que luego manipula la cola en función de los resultados? Gracias de nuevo –