2010-06-10 4 views
3

Dans cet exemple, je soumets quelques fichiers à mon objet comparateur. Tout fonctionne bien, sauf que j'ai remarqué que l'ordre dans lequel les fichiers sont soumis n'est pas toujours le même ordre dans lequel ils sont retournés. Des suggestions sur la façon dont je peux mieux contrôler cela?Comment contrôler les commandes dans lesquelles Java Futures est "soumis"?

ExecutorService pool = Executors.newFixedThreadPool(5); 
    CompletionService<Properties> completion = new ExecutorCompletionService<Properties>(pool); 

    for (String target : p.getTargetFiles()) { 
    completion.submit(new PropertiesLoader(target, p)); 
    } 

    for (@SuppressWarnings("unused") 
    String target : p.getTargetFiles()) { 
    Properties r = null; 
    try { 
    r = completion.take().get(); 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } catch (ExecutionException e) { 
    e.printStackTrace(); 
    } 

    p.addTargetFilesProperties(r); 
    } 

    pool.shutdown(); 

Répondre

3

Le point principal de l'utilisation CompletionService.take est d'avoir le retour selon Future a fini, peu importe quel ordre elles ont été soumises. Si vous voulez les retourner dans l'ordre, vous pourriez aussi bien ne pas l'utiliser du tout (vous ne voudrez peut-être même pas utiliser CompletionService, mais vous pouvez le faire). Gardez une liste des Future objets retournés par submit() et appelez le .get() sur chacun d'eux; il bloquera jusqu'à ce que le résultat soit disponible.

0

Lorsque vous soumettez plusieurs tâches à ThreadPoolExecutor en même temps, vous n'avez aucun contrôle réel sur les temps de terminaison, car ils sont exécutés simultanément par plusieurs threads. Le service d'achèvement les renvoie dans l'ordre où ils se terminent, ce qui peut varier d'une exécution à l'autre. Si vous décidez d'exécuter la tâche en série, l'ordre d'achèvement est le même que l'ordre d'activation.

--EDIT--

Si vous voulez toujours concurrency, mais veulent attendre les tâches dans un ordre spécifique, ne pas utiliser le service d'achèvement. Faites simplement une boucle sur les futures dans l'ordre requis, et appelez leur méthode get(), qui bloque si nécessaire.

Questions connexes