Sto appena iniziando a esaminare Futures e ScheduledExecutorService in Java, e mi chiedo perché il mio Callable non sia in esecuzione sul programma che ho indicato. In questo codice di esempio, il callable viene eseguito una volta, ma l'app non viene mai completata, né l'attività viene eseguita di nuovo, che è ciò che mi aspettavo che accadesse (sono sicuro che il problema è con le mie aspettative).Ricerca di Clarity su Java ScheduledExecutorService e FutureTask
I cavi funzionano correttamente; Le callebles sembrano bloccarsi per sempre, ma non sono sicuro del perché .... Cosa mi sto perdendo?
Grazie!
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());
}
}
Non sono sicuro di seguirlo. FutureTask implementa Runnable e mi aspetterei che invochi il metodo call() e memorizzi il risultato. Quindi mi aspetto che get() blocchi fino a quando il lavoro è terminato, o restituisco immediatamente il risultato memorizzato nella cache. Quindi lo scheduler non dovrebbe eseguire il FutureTask, risultando in call() e il risultato memorizzato nella cache per la successiva raccolta? –
Sì, ma solo una volta. Eventuali invocazioni programmate dopo il primo chiamerebbero 'run' sul FutureTask, ma quel metodo di esecuzione" cortocircuiti "senza richiamare' call' su Callable. Ma lo scheduler non ne è a conoscenza e continua a funzionare per richiamare il FutureTask, quindi il programma non termina. – erickson
Ha perfettamente senso. Ero così a testa bassa nelle javadoc per gli Executor e il suo genere e ho completamente perso quella linea ovvia in FutureTask. Come domanda successiva, se quello che voglio accadere come risultato del mio compito è che un BlockingQueue viene aggiornato, è preferibile passare semplicemente quella coda in ogni eseguibile, o implementare un listener che vivrebbe al di fuori del eseguibile che poi manipola la coda in base ai risultati? Grazie ancora –