Comment mettre en œuvre un ExecutorService pour exécuter des tâches sur une rotation de base?
Je suis en utilisant java.util.de façon concomitante.ExecutorService avec fixe pool de threads pour exécuter la liste de tâches. Ma liste de tâches va généralement être autour de 80 - 150 et j'ai limité le nombre de threads en cours d'exécution à tout moment à 10, comme illustré ci-dessous:
ExecutorService threadPoolService = Executors.newFixedThreadPool(10);
for ( Runnable task : myTasks )
{
threadPoolService.submit(task);
}
Mon cas d'utilisation exige que, même de la tâche réalisée doit être à nouveau soumis à nouveau à la ExecutorService mais il doit être exécuté/pris à nouveau que lorsque tous les déjà soumis tâches sont desservies/terminé. C'est essentiellement, les tâches soumis doit être exécuté sur une rotation de base. Par conséquent, il n'y aura pas soit threadPoolService.shutdown()
ou threadPoolService.shutdownNow()
appel dans ce cas.
Ma question est, comment puis-je mettre en œuvre ExecutorService l'entretien de la rotation de base des tâches?
Vous devez vous connecter pour publier un commentaire.
ThreadPoolExecutor fournit un point d'extension pour afterExecution où vous pouvez mettre le travail en arrière à la fin de la file d'attente.
Que vous aurez à faire un peu plus de travail bien sûr pour instancier vous-même sans l'aide de
ExecutorService
's pratique méthode de fabrique, mais les constructeurs sont assez simple à analyser.ThreadPoolExecutor
classe. J'ai une question, ici, de quoi/comment/pourquoi ai-je besoin de passerBlockingQueue<Runnable> workQueue
du constructeur. En cas deExecutorService
, j'ai utilisé pour présenter toutes mes tâches comme cethreadPoolService.submit(task)
. Ne suis pas en mesure de comprendre au sujet de ceBlockingQueue<Runnable> workQueue
. J'espère que vous pourrez me faire comprendre.BlockingQueue<Runnable>
et de la pensée de le mettre à jour ici.BlockingQueue
est essentiellement utilisé pour maintenir le travail/tâche qui est envoyé à l'exécuteur testamentaire lorsque tous les threads du pool sont occupés à l'exécution de ces tâches.La réponse est plus liée à la mise en œuvre de la file d'attente de travail utilisé pour l'instance de
ExecutorService
. Donc, je vous suggère de:Choisissez d'abord une mise en œuvre de
java.util.de façon concomitante.BlockingQueue
(un exemple) qui fournit une file d'attente circulaire fonctionnalité. NOTE, la raisonBlockingQueue
a été choisi, c'est que pour attendre jusqu'à la prochaine tâche de la file d'attente; ainsi, en cas de circulaire + blocage file d'attente, vous devez être prudent sur la manière de fournir le même comportement et la fonctionnalité.Au lieu d'utiliser
Executors.new...
pour créer un nouveauThreadPoolExecutor
utiliser un direct constructeur commeDe cette façon, à moins que vous commande l'exécuteur de
shutdown
, il va essayer de récupérer la tâche suivante de la file d'attente pour l'exécution de ses file d'attente de travail qui est un circulaire conteneur pour les tâches.Je propose la solution suivante qui utilise les fonctionnalités existantes dans la bibliothèque standard de simultanéité utils. Il utilise un
CyclicBarrier
avec une tâche décorateur de classe et un obstacle à l'action qui re-soumet toutes les tâches:Vous pouvez simplement vérifier que toutes les tâches ont été exécutées et les soumettre de nouveau une fois que c'est le cas, comme ceci par exemple:
MODIFIER
Il semble que vous voulez soumettre une tâche dès qu'il est achevé. Vous pouvez utiliser un ExecutorCompletionService qui vous permet de récupérer des tâches lorsqu'elles sont exécutées, - voir ci-dessous un exemple simple avec 2 tâches que soumis de nouveau à quelques reprises dès qu'ils sont terminés. Exemple de sortie:
wait until completion of all tasks
. Toutes les idées/commentaires?