183 votes

Simultanéité de Java : barrière de cyclique vs compte à rebours de verrouillage

Je lisais le java.util.simultanée de l'API, et a constaté que

  • CountDownLatch: Une synchronisation de l'aide qui permet à un ou plusieurs threads d'attendre jusqu'à ce qu'un ensemble d'opérations effectuées dans d'autres threads complète.
  • CyclicBarrier: Une synchronisation de l'aide qui permet à un ensemble de threads à tous d'attendre les uns des autres, pour arriver à une barrière point.

Pour moi les deux semble égal, mais je suis sûr qu'il ya beaucoup plus à elle.

Par exemple, en CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier.

Est-il une autre différence entre les deux?
Quels sont les use cases où quelqu'un voudrait pour réinitialiser la valeur du compte à rebours?

150voto

Kim Points 449

Il y a une autre différence.

Lors de l'utilisation d'un CyclicBarrier, l'hypothèse est que vous spécifiez le nombre de threads en attente de déclenchement de la barrière. Si vous spécifiez 5, vous devez avoir au moins 5 threads d'appeler await().

Lors de l'utilisation d'un CountDownLatch, vous spécifiez le nombre d'appels à l' countDown() qui fera en sorte que tous les threads en attente d'être libéré. Cela signifie que vous pouvez utiliser un CountDownLatch avec un seul thread.

"Pourquoi voudriez-vous faire cela?", vous pouvez dire. Imaginez que vous êtes à l'aide d'un mystérieux API codé par quelqu'un d'autre qui effectue des rappels. Vous souhaitez qu'un de vos fils d'attendre un certain rappel a été appelé un certain nombre de fois. Vous n'avez aucune idée de qui fils le callback sera appelé. Dans ce cas, un CountDownLatch est parfaite, alors que je ne peux pas penser à une façon de mettre en œuvre ce à l'aide d'un CyclicBarrier (en fait, je peux, mais il implique des délais d'attente... beurk!).

Je souhaite juste qu' CountDownLatch pourrait être remis à zéro!

146voto

Jon Points 23749

Une différence importante est que CyclicBarrier prend une (facultatif) Praticable tâche est exécutée une fois l'obstacle commun condition est remplie.

Il vous permet aussi d'obtenir le nombre de clients en attente à la barrière et le nombre requis pour déclencher la barrière. Une fois déclenché, l'obstacle est remise à zéro et peut être utilisé à nouveau.

Pour des cas d'utilisation simples - services etc... un CountdownLatch est très bien. Un CyclicBarrier est utile pour les plus complexes des tâches de coordination. Un exemple d'une telle chose serait de calcul parallèle - où plusieurs sous-tâches sont impliqués dans le calcul, un peu comme MapReduce.

48voto

Chirlo Points 1861

Un point que personne n'a encore mentionné, c'est que, en CyclicBarrier, si un thread a un problème (délai d'attente, interrompue...), tous les autres qui ont atteint await() obtenez une exception. Voir La Javadoc:

Le CyclicBarrier utilise un tout-ou-rien bris modèle de l'échec des tentatives de synchronisation: Si un thread laisse une barrière point prématurément en raison d'une interruption, d'échec ou de délai d'attente, tous les autres threads en attente à la barrière point permettra également de laisser anormalement via BrokenBarrierException (ou InterruptedException si ils ont été interrompus à la même époque).

14voto

JohnnyO Points 2130

La principale différence est documenté à droite dans la Javadoc CountdownLatch. À savoir:

Un CountDownLatch est initialisé avec un compte tenu de comte. L'attendent méthodes bloc jusqu'à ce que le compte à rebours atteint zéro en raison des invocations du compte à rebours() la méthode d'après laquelle tous en attente les threads sont libérés et tout des appels successifs de attendent le retour immédiatement. C'est un one-shot phénomène -- le comte ne peut pas être réinitialiser. Si vous avez besoin d'une version réinitialise le comte, pensez à utiliser un CyclicBarrier.

source 1.6 Javadoc

13voto

shams Points 1986

Un CountDownLatch est utilisé pour la synchronisation de l'heure. Lors de l'utilisation d'un CountDownLatch, n'importe quel thread est autorisé à suivre le compte à rebours() autant de fois qu'ils le souhaitent. Fils appelé await() sont bloqués jusqu'à ce que le compte à rebours atteint zéro, à cause des appels à compte à rebours() par d'autres débloqué threads. La javadoc de CountDownLatch états:

L'attendent méthodes de bloc jusqu'à ce que le compte à rebours atteint zéro, suite à les invocations du compte à rebours() la méthode d'après laquelle tous les threads en attente sont libérées et toutes les invocations de attendent le retour immédiatement. ...

Un autre exemple d'utilisation serait de diviser un problème en N parties, décrire chaque partie avec un Exécutable qui s'exécute la partie et le compte à rebours sur le loquet, et la file d'attente tous les Runnables à un Exécuteur testamentaire. Lorsque toutes les sous-parties sont complets, la coordination du fil sera en mesure pour passer à travers les attendent. (Lorsque les threads doivent à plusieurs reprises décompte en de cette façon, au lieu d'utiliser un CyclicBarrier.)

En revanche, cyclique, la barrière est utilisée pour plusieurs martiens points, par exemple, si un ensemble de threads sont en cours d'exécution d'une boucle/progressive de calcul et de besoin de synchroniser avant de commencer la prochaine itération/phase. Selon la javadoc pour CyclicBarrier:

La barrière est appelé cyclique, car il peut être ré-utilisées après la les threads en attente de libération.

Contrairement à la CountDownLatch, chaque appel à await() appartient à une phase et le fil de bloquer jusqu'à ce que toutes les parties appartenant à cette phase ont invoqué await(). Il n'est pas explicite, compte à rebours() de l'opération pris en charge par le CyclicBarrier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X