java Fork / Join pool, ExecutorService et CountDownLatch

nous avons trois différentes techniques de threading multi en java - Fork/Join pool, Executor Service & CountDownLatch

Fork/Join pool ( http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel-programming.html )

le cadre fourche/Join est conçu pour rendre les algorithmes divide-and-conquer faciles à paralléliser. Ce type d'algorithmes est parfait pour des problèmes qui peuvent être divisés en deux ou plusieurs sous-problèmes du même type. Ils utilisent la récursion pour décomposer le problème en tâches simples jusqu'à ce que ceux-ci deviennent assez simples pour être résolus directement. Les solutions aux sous-problèmes sont ensuite combinées pour donner une solution au problème original

ExecutorService est une interface qui étend la classe Executor et représente une exécution asynchrone. Il nous fournit des mécanismes pour gérer fin et de détecter les progrès de l'tâches asynchrones.

invokeAll () : exécute les tâches données, en retournant une liste de futurs détenant leur statut et les résultats lorsque tous terminés. Avenir.isDone() est vrai pour chaque élément de la liste retournée.

CountDownLatch : ( http://examples.javacodegeeks.com/core-java/util/concurrent/countdownlatch-concurrent/java-util-concurrent-countdownlatch-example / )

CountDownLatch est utilisé en synchronisation pour permettre à un ou plusieurs threads d'attendre qu'un ensemble d'opérations effectuées dans d'autres threads soit terminé.

mon hypothèse:

dans ces deux alternatives, le résultat final ne sera connu qu'après achèvement de toutes les tâches/threads.

ces trois variantes sont-elles complémentaires ou complémentaires l'une de l'autre ?

1
demandé sur Ravindra babu 2015-07-23 11:54:11

1 réponses

après des recherches sur divers cadres de multi-threading pour les 3 derniers mois , j'ai trouvé réponse à la question.

ExecutorService

, C'est simple et facile à utiliser avec un contrôle limité. Vous pouvez l'utiliser

  1. pour commencer des tâches indépendantes parallèles sans attendre
  2. attendez l'achèvement de toutes vos tâches

I préférez celui-ci lorsque le nombre de Callable/Runnable tâches sont petites en nombre et l'accumulation de tâches dans la file d'attente sans limite ne provoque pas l'accumulation en mémoire et dégrader la performance du système.

il cache des détails de bas niveau de ThreadPoolExecutor . Il ne permet pas de jouer avec d'autres paramètres ( Bounded Queue, Rejection Handler etc. pour affiner la performance) comme dans ThreadPoolExectuor .

ThreadPoolExecutor

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)

il vous donne plus de contrôle. En plus de définir les threads minimum et maximum, vous pouvez définir la taille de la file d'attente et faire BlockingQueue est limité.

vous pouvez venir avec votre propre usine de filetage si vous avez besoin des caractéristiques ci-dessous""

  1. pour définir un nom de fil plus descriptif
  2. pour définir le statut de démon thread
  3. pour définir la priorité du fil

si votre l'application est limitée par le nombre de tâches exécutables/appelables en attente, vous utiliserez la file d'attente bornée en définissant la capacité maximale. Une fois que la file d'attente atteint sa capacité maximale, vous pouvez définir RejectionHandler. Java fournit quatre types de gestionnaire de rejet politiques .

  1. par défaut ThreadPoolExecutor.AbortPolicy , le gestionnaire jette un runtime RejectedExecutionException le rejet.

  2. dans ThreadPoolExecutor.CallerRunsPolicy , le fil qui invoque exécuter lui-même exécute la tâche. Il s'agit d'un mécanisme simple de contrôle de la rétroaction qui ralentira le rythme de présentation des nouvelles tâches.

  3. Dans ThreadPoolExecutor.DiscardPolicy , une tâche qui ne peut être exécutée est tout simplement abandonné.

  4. Dans ThreadPoolExecutor.DiscardOldestPolicy , si l'exécuteur testamentaire n'est pas arrêté, la tâche à la tête de la file d'attente de travail est supprimé, et l'exécution est rejoué (ce qui peut échouer à nouveau, ce qui fait que cela se répète.)

CountDownLatch

CountDownLatch : ce framework permet à un thread java d'attendre que d'autres threads aient terminé leurs tâches.

cas d'Utilisation:

  1. atteindre parallélisme maximal : parfois, nous voulons commencer un certain nombre de fils en même temps pour obtenir un parallélisme maximum

  2. attendre que N threads complète avant le début de l'exécution autre bloc de code

  3. détection de Blocage.

plus de détails sont énumérés dans ce article

ForkJoinPool

le ForkJoinPool est similaire au Java ExecutorService mais avec une différence. Le ForkJoinPool permet aux tâches de diviser leur travail en tâches plus petites qui sont ensuite soumises à la ForkJoinPool aussi. Le vol de tâches se produit dans ForkJoinPool quand des threads d'ouvrier libres volent des tâches de la file d'attente d'ouvrier occupée.

public ForkJoinPool(int parallelism,
            ForkJoinPool.ForkJoinWorkerThreadFactory factory,
            Thread.UncaughtExceptionHandler handler,
            boolean asyncMode)
Creates a ForkJoinPool with the given parameters.

paramètres:

parallélisme - le niveau de parallélisme. Pour valeur par défaut, utilisez Runtime.availableProcessors() .

usine - l'usine pour créer de nouveaux fils. Pour la valeur par défaut, utilisez defaultForkJoinWorkerThreadFactory.

handler - le handler pour les fils de travail internes qui se terminent en raison d'erreurs irrécupérables

asyncMode - si elle est vraie, établit le mode de programmation Local premier entré premier sorti pour les tâches fourchues qui ne sont jamais Unis.

concernant la requête principale:

vous pouvez utiliser ExecutorService.invokeAll() ou CountDownLatch framework ou ForkJoinPool . Tous ces cadres sont complémentaires les uns des autres variant de granularité pour contrôler l'exécution des tâches de haut niveau à bas niveau.

EDIT:

regardez liées SE questions:

Quels sont les avantages d'utiliser un ExecutorService?

Java Fork / Join vs ExecutorService-when to use which?

7
répondu Ravindra babu 2017-05-23 12:10:22