7
votes

Comment mettre en œuvre un opérateur exécutant pour exécuter des tâches sur une base de rotation?

J'utilise Java.util. concurrent.executerservice avec Pool de threads fixe pour exécuter la liste des tâches. Ma liste de tâches sera généralement d'environ 80 - 150 et j'ai limité le nombre de threads fonctionnant à tout moment à 10, comme indiqué ci-dessous: XXX

Mon cas d'utilisation exige que même la tâche terminée. devrait être re-soumis à nouveau à la exécutorservice mais elle doit être exécutée / prise à nouveau lorsque toutes les tâches soumises déjà sont desservies / complétées. C'est fondamentalement, les tâches soumises doivent être exécutées à la rotation. Par conséquent, il n'y aura pas non plus threadpoolservice.shutdown () ou threadpoolservice.shutdownNow () appel dans ce cas.

Ma question est, comment faire I Mise en œuvre exécutantservice entretien des tâches de base de la rotation?


0 commentaires

4 Réponses :


12
votes

threadpoolEcutor fournit un point d'extension de l'après -exécution où vous pouvez remettre le travail à la fin de la file d'attente.

public class TaskRepeatingThreadPoolExecutor extends ThreadPoolExecutor {

    public TaskRepeatingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        this.submit(r);
    }
}


3 commentaires

Merci de cette suggestion et de me faire connaître l'existence de threadpoolexecutor classe. J'ai une question ici, quoi / comment / pourquoi dois-je passer blockingQueue WorkQueue au constructeur. Dans le cas de exécutantservice , j'ai utilisé toutes mes tâches telles que celles-ci threadpoolservice.submit (tâche) . Je ne suis pas capable de comprendre à propos de ce blocingQueue WorkQueue . J'espère que vous pourrez me faire comprendre cela.


Il suffit de lire sur BlockingQueue et pensé à la mise à jour ici. BlockingQueue est essentiellement utilisé pour contenir le travail / la tâche qui est envoyé à l'exécuteur exécuté lorsque tous les threads de la piscine sont occupés à exécuter les tâches.


Je ne suis pas sûr que cette technique fonctionne, la posée est appelée avec FutureTask (Runnable - Wrapper autour de la tâche réelle) qui présente un état interne qui conserve la trace du statut d'achèvement. Si RE Soumis, il ne vient que de retourner sans exécuter la tâche réelle.



1
votes

La réponse est plus liée à la mise en œuvre de la queue utilisée pour l'instance de exécutorservice . Donc, je suggérerais:

  1. Choisissez d'abord une implémentation de java.util.concurrent.BlockingQueue ( Un exemple ) qui fournit une fonctionnalité file d'attente circulaire . note , la raison blockingqueue a été choisie est que pour attendre jusqu'à ce que la tâche suivante soit fournie à la file d'attente; Donc, dans le cas de la queue circulaire + bloquant , vous devez faire attention à fournir le même comportement et la même fonctionnalité.

  2. au lieu d'utiliser exécuteurs.new ... Pour créer un nouveau threadpoolexecuteur Utilisez un constructeur direct tel que

    ThreadPoolEcutor (int CorePoolSize, int maximumpoolsize, maintenance longue, unité TimeUnit, blocageQueue WorkQueue)

    De cette façon, sauf si vous commandez l'exécuteur exécutante à Arrêter , il tentera de récupérer la tâche suivante à partir de la file d'attente d'exécution à partir de sa la queue de travail qui est Circulaire conteneur pour tâches.


0 commentaires

1
votes

Je suggère la solution suivante qui utilise complètement la fonctionnalité existant dans l'utils de concurrence de la bibliothèque standard. Il utilise un cyclicbarrier avec une classe de décorateur de tâches et une action de barrière qui soumet toutes les tâches: xxx


0 commentaires

1
votes

Vous pouvez simplement vérifier que toutes les tâches ont été exécutées et les resoumettre une fois que c'est le cas, comme celui-ci, par exemple: xxx

modifier
Il semble que vous souhaitiez soumettre à nouveau une tâche dès qu'il sera terminé. Vous pouvez utiliser un ExecutorCompletservice qui permet. Vous devez récupérer des tâches comme et quand ils sont exécutés, voir ci-dessous un exemple simple avec 2 tâches qui sont soumises à nouveau quelques fois dès leur complétude. Sortie d'échantillon:

Tâche 1 Piscine soumise-1-thread-1
Tâche 2 Piscine soulevée-1-thread-2
Tâche 1 Terminé Pool-1-Thread-1
Tâche 1 Piscine soumise-1-thread-3
Tâche 2 Piscine terminée-1-thread-2
Tâche 1 Piscine terminée-1-thread-3
Tâche 2 Piscine soulevée-1-thread-4
Tâche 1 Piscine soumise-1-thread-5
Tâche 1 Piscine terminée-1-thread-5
Tâche 2 Piscine terminée-1-thread-4 xxx


2 commentaires

Dans mon cas, j'ai besoin de soumettre à nouveau toutes les tâches individuelles comme et quand il est terminé, mais pas à attendre la fin de toutes les tâches . Des idées / commentaire?


Cool! C'est ce que je cherche. Merci.