Je commence juste à regarder dans Futures et le ScheduledExecutorService dans Java, et je me demande pourquoi mon Callable ne fonctionne pas sur l'horaire que j'ai indiqué. Dans cet exemple de code, l'appelable s'exécute une fois, mais l'application ne se termine jamais, et la tâche ne s'exécute plus, ce qui est ce que je m'attendais à arriver (je suis sûr que le problème est avec mes attentes).À la recherche de la clarté sur Java ScheduledExecutorService et FutureTask
Les exécutions fonctionnent correctement; Les callables semblent bloquer pour toujours, mais je ne sais pas pourquoi ... Qu'est-ce qui me manque?
Merci!
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());
}
}
Je ne suis pas sûr de suivre cela. FutureTask implémente Runnable, et je m'attendrais à ce qu'il appelle la méthode call(), et stocke le résultat. Je m'attendrais alors à ce que get() bloque jusqu'à ce que le travail soit fini, ou renvoie le résultat caché immédiatement. Donc, le planificateur n'exécuterait-il pas FutureTask, ce qui entraînerait call() et le résultat serait mis en cache pour une collecte ultérieure? –
Oui, mais seulement une fois. Toutes les invocations planifiées après la première appelaient 'run' sur la FutureTask, mais cette méthode d'exécution« court-circuite »sans invoquer' call' sur Callable. Mais le planificateur n'est pas conscient de cela et continue de fonctionner pour appeler la FutureTask, de sorte que le programme ne se termine pas. – erickson
Cela prend tout son sens. J'étais tellement tête baissée dans les javadocs pour les Executors et ses semblables et j'ai complètement raté cette ligne évidente dans FutureTask. Comme une question suivante, si ce que je veux arriver à la suite de ma tâche est qu'un BlockingQueue est mis à jour, est-il préférable de simplement passer cette file dans chaque runnable, ou d'implémenter un écouteur qui vivrait en dehors du runnable qui manipule ensuite la file d'attente en fonction des résultats? Merci encore –