2017-04-07 4 views
0

J'utilise ExecutorCompletionService pour obtenir le résultat des travaux dès qu'il termine son exécution. Pseudocode est comme this-
Mode correct pour obtenir la sortie de ExecutorCompletionService

Instantiate FixedThreadPool executor, exec 
Instantiate ExecutorCompletionService, completionService 
for(taskList) { 
    completionService.submit(someTask) 
} 
exec.shutDown(); 
whie(!exec.isShutdown()) { //Line 1 
    Task t = completionService.take(); //Line 2 
} 

Comme nous le savons, shutdown() attend l'achèvement de toutes les tâches soumises, alors tant qu'il est une tâche en cours tout état sur Ligne1 retourne vrai et le code va à l'intérieur de la boucle pour prendre la tâche terminée de la file d'attente et attend si nécessaire.
Maintenant, j'ai observé un problème avec le code ci-dessus dans lequel le contrôle est bloqué sur la ligne 2 même s'il n'y a plus de tâches en cours, toutes les tâches ont été accomplies.
Je pense que c'est parce que lorsque la dernière tâche est terminée et ajoutée à la file d'attente de fin, ThreadPoolExecutor reprend le processus d'arrêt car il n'y a plus de tâches soumises en attente. Mais alors qu'il était encore en train de s'éteindre, l'itération suivante a lieu et isShutdown() renvoie false alors il entre dans la boucle et est bloqué par l'appel take() même s'il n'y a plus de tâches. Alors peut-être que c'est le temps entre l'appel take et la fermeture de la piscine correctement. Est-ce que je pense dans la bonne direction?
Alors je me demandais si c'était la bonne façon d'utiliser et d'obtenir le résultat de completionservice? Pour résoudre ce problème, je peux remplacer le while sur la ligne 1 par for(taskList) afin d'éviter l'appel isShutdown. Il y a une autre chose, est-ce la meilleure pratique pour éteindre l'exécuteur, puis obtenir le résultat de completionservice ou d'abord recueillir le résultat et arrêter l'execturo à la fin?

Répondre

0

Essayez d'utiliser isTerminated() au lieu de isShutoown(). Mais le meilleur choix sera d'utiliser la méthode awaitTermination() au lieu de créer cette boucle.