Estaba leyendo la API java.util.concurrent y descubrí que
CountDownLatch
: Una ayuda de sincronización que permite que uno o más subprocesos esperen hasta que se complete un conjunto de operaciones que se realizan en otros subprocesos.CyclicBarrier
: Una ayuda de sincronización que permite que un conjunto de subprocesos esperen entre sí para llegar a un punto de barrera común.
Para mí, ambos parecen iguales, pero estoy seguro de que hay mucho más.
Por ejemplo, en CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier
.
¿Hay alguna otra diferencia entre los dos?
¿En qué use cases
lugar querría alguien restablecer el valor de la cuenta regresiva?
java
concurrency
countdownlatch
cyclicbarrier
soñador
fuente
fuente
Respuestas:
Una diferencia importante es que CyclicBarrier toma una tarea Ejecutable (opcional) que se ejecuta una vez que se cumple la condición de barrera común.
También le permite obtener el número de clientes que esperan en la barrera y el número requerido para activar la barrera. Una vez activada, la barrera se restablece y se puede volver a usar.
Para casos de uso simples: servicios que comienzan, etc., CountdownLatch está bien. Un CyclicBarrier es útil para tareas de coordinación más complejas. Un ejemplo de tal cosa sería la computación paralela, donde múltiples subtareas están involucradas en la computación, algo así como MapReduce .
fuente
Hay otra diferencia
Cuando se utiliza a
CyclicBarrier
, se supone que especifica el número de subprocesos en espera que activan la barrera. Si especifica 5, debe tener al menos 5 hilos para llamarawait()
.Cuando se utiliza a
CountDownLatch
, se especifica la cantidad de llamadascountDown()
que dará como resultado la liberación de todos los hilos en espera. Esto significa que puede usarCountDownLatch
un solo hilo."¿Por qué harías eso?", Puedes decir. Imagine que está utilizando una API misteriosa codificada por otra persona que realiza devoluciones de llamada. Desea que uno de sus hilos espere hasta que se haya llamado una cierta devolución de llamada varias veces. No tiene idea de qué hilos se llamará a la devolución de llamada. En este caso, a
CountDownLatch
es perfecto, mientras que no se me ocurre ninguna forma de implementar esto usando aCyclicBarrier
(en realidad, puedo, pero implica tiempos de espera ... ¡qué asco!).¡Solo deseo que se
CountDownLatch
pueda restablecer!fuente
CountDownLatch
poder reiniciarse: una solución alternativa que uso para implementar una notificación de espera aproximada es simplemente renovarCountDownLatch
inmediatamente cuando se ingresa el bloque de código protegido (cuando el pestillo llega a cero). Esto no es aplicable en todas las circunstancias / ámbitos, por supuesto, pero pensé que vale la pena señalar que es una opción en situaciones de Ricitos de Oro.Java Concurrency in Practice
- dice lo mismo:Latches are for waiting for events; barriers are for waiting for other threads.
. Un punto primario y esencial para entender la diferencia entre estos dos.Un punto que nadie ha mencionado aún es que, en un
CyclicBarrier
caso, si un hilo tiene un problema (tiempo de espera, interrumpido ...), todos los demás que han llegadoawait()
obtienen una excepción. Ver Javadoc:fuente
Creo que JavaDoc ha explicado las diferencias explícitamente. La mayoría de las personas saben que CountDownLatch no se puede restablecer, sin embargo, CyclicBarrier sí. Pero esta no es la única diferencia, o el CyclicBarrier podría renombrarse a ResetbleCountDownLatch. Deberíamos distinguir las diferencias desde la perspectiva de sus objetivos, que se describen en JavaDoc
CountDownLatch: una ayuda de sincronización que permite que uno o más subprocesos esperen hasta que se complete un conjunto de operaciones que se realizan en otros subprocesos.
CyclicBarrier: una ayuda de sincronización que permite que un conjunto de subprocesos esperen entre sí para llegar a un punto de barrera común.
En countDownLatch, hay uno o más subprocesos que esperan que se complete un conjunto de otros subprocesos . En esta situación, hay dos tipos de subprocesos, un tipo está esperando, otro tipo está haciendo algo, después de finalizar sus tareas, podrían estar esperando o simplemente terminados.
En CyclicBarrier, solo hay un tipo de subprocesos, se están esperando, son iguales.
fuente
La principal diferencia se documenta directamente en los Javadocs para CountdownLatch. A saber:
fuente 1.6 Javadoc
fuente
Se utiliza un CountDownLatch para la sincronización de una sola vez. Mientras usa un CountDownLatch, cualquier hilo puede llamar a countDown () tantas veces como quiera. Los subprocesos que llamaron a waitit () se bloquean hasta que el recuento llega a cero debido a llamadas a countDown () por otros subprocesos desbloqueados. El javadoc para CountDownLatch dice:
Por el contrario, la barrera cíclica se utiliza para múltiples puntos de sincronización, por ejemplo, si un conjunto de subprocesos ejecuta un cálculo en bucle / en fase y necesita sincronizarse antes de comenzar la siguiente iteración / fase. Según el javadoc para CyclicBarrier :
A diferencia de CountDownLatch, cada llamada a await () pertenece a alguna fase y puede hacer que el hilo se bloquee hasta que todas las partes que pertenecen a esa fase hayan invocado a wait (). No hay una operación explícita countDown () compatible con CyclicBarrier.
fuente
Esta pregunta ya ha sido respondida adecuadamente, pero creo que puedo agregar un poco de valor al publicar un código.
Para ilustrar el comportamiento de la barrera cíclica, hice un código de muestra. Tan pronto como se inclina la barrera, se restablece automáticamente para que pueda usarse nuevamente (por lo tanto, es "cíclica"). Cuando ejecute el programa, observe que las impresiones "Vamos a jugar" se activan solo después de que se inclina la barrera.
fuente
Cuando estudiaba sobre pestillos y barreras cíclicas, se me ocurrió esta metáfora. barreras cíclicas : imagine que una empresa tiene una sala de reuniones. Para comenzar la reunión, un cierto número de asistentes a la reunión tienen que venir a la reunión (para que sea oficial). el siguiente es el código de un asistente de reunión normal (un empleado)
el empleado se une a la reunión, espera a que otros vengan para comenzar a reunirse. también se sale si la reunión se cancela :) entonces tenemos THE BOSS cómo a las dosis no les gusta esperar a que otros se presenten y si pierde a su paciente, cancela la reunión.
En un día normal, los empleados vienen a la reunión y esperan que otros se presenten, y si algunos de los asistentes no vienen, ¡tienen que esperar indefinidamente! en alguna reunión especial, el jefe viene y no le gusta esperar (5 personas deben comenzar a reunirse, pero solo viene el jefe y también un empleado entusiasta), por lo que cancela la reunión (enojado)
Salida:
Hay otro escenario en el que otro hilo externo (un terremoto) cancela la reunión (método de restablecimiento de llamada). en este caso, todos los hilos de espera se despiertan por una excepción.
ejecutar código dará como resultado una salida divertida:
También puede agregar una secretaria a la sala de reuniones, si se celebra una reunión, documentará todo pero no formará parte de la reunión:
Cierres : si el jefe enojado quiere organizar una exhibición para los clientes de la compañía, todo debe estar listo (recursos). proporcionamos una lista de tareas pendientes a cada trabajador (Hilo) que dosifica su trabajo y verificamos la lista de tareas pendientes (algunos trabajadores pintan, otros preparan el sistema de sonido ...). Cuando todos los elementos de la lista de tareas están completos (se proporcionan recursos), podemos abrir las puertas a los clientes.
Y los trabajadores cómo están preparando la exposición:
fuente
En pocas palabras , solo para comprender las diferencias funcionales clave entre los dos:
y
excepto, por supuesto, características como no bloqueo, espera temporizada, diagnósticos y todo lo que se ha explicado en detalle en las respuestas anteriores.
Sin embargo, las clases anteriores son completamente funcionales y equivalentes, dentro de la funcionalidad proporcionada, a sus homónimos correspondientes.
En una nota diferente,
CountDownLatch
las subclases de clase internaAQS
, mientrasCyclicBarrier
usaReentrantLock
(mi sospecha es que podría ser al revés o que ambas podrían usar AQS o ambas usan Lock, sin ninguna pérdida de eficiencia de rendimiento)fuente
Una diferencia obvia es que solo N hilos pueden esperar en un CyclicBarrier of N para ser liberados en un ciclo. Pero puede esperar un número ilimitado de subprocesos en un CountDownLatch de N. El decremento de la cuenta regresiva puede realizarse por un subproceso N veces o N subprocesos una vez cada uno o combinaciones.
fuente
En el caso de CyclicBarrier, tan pronto como TODOS los hilos secundarios comiencen a llamar a barrera.await (), el Runnable se ejecuta en la Barrera. La barrera. Espere en cada subproceso secundario tomará una duración de tiempo diferente para terminar, y todos terminan al mismo tiempo.
fuente
En CountDownLatch , los subprocesos principales esperan que otros subprocesos completen su ejecución. En CyclicBarrier , los subprocesos de trabajo esperan entre sí para completar su ejecución.
No puede reutilizar la misma instancia de CountDownLatch una vez que el recuento llega a cero y el pestillo está abierto, por otro lado, CyclicBarrier puede reutilizarse restableciendo la barrera, una vez que se rompe la barrera.
fuente
CountDownLatch es una cuenta regresiva de cualquier cosa; CyclicBarrier es una cuenta regresiva solo para hilo
suponga que hay 5 hilos de trabajo y un hilo de remitente, y cuando los trabajadores producen 100 artículos, el remitente los enviará.
Para CountDownLatch, el contador puede estar en trabajadores o artículos
Para CyclicBarrier, el contador solo puede en trabajadores
Si un trabajador se duerme infinitamente, con CountDownLatch en los artículos, Shipper puede enviar; Sin embargo, con CyclicBarrier, Shipper nunca puede ser llamado
fuente
@Kevin Lee y @Jon Probé CyclicBarrier con Opcional Runnable. Parece que se ejecuta al principio y después de que se inclina el CyclicBarrier. Aquí está el código y la salida
barrera de barrera estática cíclica;
Salida
fuente