example java concurrency conceptual

java - example - Ejemplos de la vida real para CountDownLatch y CyclicBarrier



countdownlatch java example (8)

Ejemplo del mundo real Puedo ver que a todas las respuestas les falta un ejemplo real. Como en cómo estas clases pueden ser usadas en un reino de software.

  1. CountDownLatch Un gestor de descargas multiproceso. El administrador de descargas iniciará varios subprocesos para descargar cada parte del archivo simultáneamente (siempre que el servidor admita varios subprocesos para descargar). Aquí, cada subproceso llamará a un método de cuenta atrás de un pestillo instanciado. Después de que todos los subprocesos hayan finalizado su ejecución, el subproceso asociado con el cierre de cuenta atrás integrará las partes encontradas en las diferentes piezas juntas en un solo archivo

  2. CyclicBarrier El mismo escenario anterior. Pero supongamos que los archivos se descargan de P2P. De nuevo múltiples hilos descargando las piezas. Pero aquí, supongamos que desea que la verificación de la interferencia de las piezas descargadas se realice después de un intervalo de tiempo particular. Aquí la barrera cíclica juega un papel importante. Después de cada intervalo de tiempo, cada subproceso esperará en la barrera para que el subproceso asociado con cyclibarrier pueda realizar la comprobación de integridad. Esta comprobación de integridad se puede realizar varias veces gracias a CyclicBarrier

Por favor, corrígeme si algo no es correcto.

Uno de nuestros entrenadores nos da un ejemplo cuando explicaba la diferencia entre CountDownLatch y CyclicBarrier.

CountDownLatch : Supongamos que una piedra puede ser levantada por 10 personas, por lo que esperará a que lleguen las 10. Solo así podrás levantar la piedra.

CyclicBarrier : Si vas a un picnic, y primero debes encontrarte en algún punto común desde donde todos comenzarán tu viaje.

Si alguien está de acuerdo con estos comentarios, por favor, dame algunos detalles.

Ya he leído la API de sun para estas dos clases. Pero necesito un poco más de explicación.


En un teatro hipotético,

Se llama Mutex si solo una persona permite ver la obra.
se llama Semáforo si N número de personas permite ver la obra. Si alguien sale del Teatro durante la obra, se le puede permitir a otra persona que la vea.
se llama CountDownLatch si nadie permite entrar hasta que todas las personas abandonen el teatro. Aquí, cada persona tiene libre albedrío para abandonar el teatro.
se llama Cyclicbarrier si el teatro no se iniciará hasta que cada persona ingrese al teatro. Aquí el showman no puede comenzar el show hasta que toda la persona ingrese y tome el asiento. Una vez que finalice el juego, se aplicará la misma barrera para el próximo show

Aquí, la persona es Hilo, el juego es un recurso.


La diferencia clave es que CountDownLatch separa los subprocesos en meseros y arrivers, mientras que todos los subprocesos que usan un CyclicBarrier realizan ambos roles.

  • Con un pestillo, los camareros esperan a que llegue el último hilo que llega, pero los hilos que llegan no lo hacen ellos mismos.
  • Con una barrera, todos los hilos llegan y luego esperan a que llegue el último.

Su ejemplo de traba implica que las diez personas deben esperar para levantar la piedra juntos. Este no es el caso. Un mejor ejemplo del mundo real sería un indicador de examen que espera pacientemente a que cada estudiante entregue su examen. Los estudiantes no esperan una vez que completan sus exámenes y son libres de irse. Una vez que el último estudiante entrega el examen (o el tiempo límite expira), el indicador deja de esperar y se va con las pruebas.


Un CyclicBarrier es reutilizable, por lo que es más como un CyclicBarrier carreras en el que todos se reúnen en un punto intermedio antes de continuar en el siguiente tramo del tour.


Una barrera cíclica, como su nombre indica, puede usarse en ciclos. Por ejemplo: soy un empleado de la compañía que busca N números de currículums de varias fuentes del portal de trabajo. Tengo una matriz de habilidades que contiene habilidades ordenadas por orden de prioridad. Para ex java, c #, python. Quiero encontrar N hojas de vida que coincidan con el conjunto de habilidades de Java, pero si no encuentro el no requerido. De los currículos, busco de nuevo en el siguiente conjunto de habilidades y así sucesivamente.

Creo un trabajador, cada uno de los cuales escanea los resúmenes, en las fuentes de trabajo asignadas. Ambos trabajadores comenzarán con la búsqueda de habilidades principales en sus feeds de trabajo.

Después de realizar la búsqueda, el trabajador comprobará si se encontraron los N curriculums vitae. Si se encuentra, el trabajador restablecerá la barrera y regresará. De lo contrario, esperará a que el otro trabajador complete. Si aún no se encontraron N hojas de vida, la búsqueda se reanudaría nuevamente, en la siguiente habilidad en el conjunto de habilidades. Por lo tanto, la búsqueda se puede llamar de forma recursiva / cíclica sin necesidad de crear una nueva barrera cíclica.


Caso de uso 1 Suponga que ha dividido un trabajo grande en 10 tareas pequeñas, cada una de ellas un hilo. Debe esperar el final de las 10 tareas de esos subprocesos antes de considerar el trabajo realizado.

Por lo tanto, el subproceso principal del iniciador de trabajo inicializa CountDownLatch con el número de subprocesos utilizados, distribuye las tareas a los subprocesos y espera que el pestillo aumente en cero con el método de await . Cada hilo ejecutor invocará countDown al final de su tarea. Finalmente, el hilo principal se activará cuando todos los hilos hayan finalizado, por lo que considera que se ha completado todo el trabajo. Este escenario usa el doneSignal descrito en el javadoc CountDownLatch.

Caso de uso 2 Suponga que ha dividido un trabajo grande en tareas * m, distribuidas en n subprocesos. m corresponde a una fila de matriz y tiene un total que calcular para cada fila. En ese caso, los subprocesos deben sincronizarse después de que finalice cada tarea para que el total de la fila sea el cálculo. En ese caso, se CyclicBarrier un CyclicBarrier inicializado con el número de subprocesos n para esperar el final de cada cálculo de fila (de hecho, m veces).

Para comparar ambos, CountDownLatch se supone que se debe usar solo 1 vez y se puede usar un CyclicBarrier tantas veces como el algoritmo requiera un punto de sincronización para un conjunto de subprocesos.


CountDownLatch: si queremos que todos nuestros hilos hagan

algo + cuenta regresiva

para que otros hilos en espera (para que el conteo llegue a cero) puedan continuar, podemos usar el bloqueo de cuenta atrás. Todos los subprocesos anteriores que realmente hicieron la cuenta atrás pueden continuar en esta situación, pero no hay garantía de que la línea procesada después de latch.countdown () esté después de esperar a que otros subprocesos lleguen a latch.countdown (), pero tiene una garantía de que otros los subprocesos en espera solo comenzarán más allá de que latch.await () haya llegado a cero.

CyclicBarrier: Si queremos que todo nuestro hilo sea

hacer algo + esperar en el punto común + hacer algo

(cada llamada en espera disminuirá el tiempo de espera para que los hilos continúen)

La funcionalidad de CyclicBarrier se puede lograr con CountDownLatch solo una vez llamando a latch.countdown () seguido de latch.await () por todos los subprocesos.

pero una vez más no puede restablecer / reutilizar la cuenta regresiva.

El mejor ejemplo en el que usé CyclicBarrier es para inicializar múltiples cachés (calentados por múltiples hilos) y luego comenzar un procesamiento adicional, y quería reinicializar otros cachés nuevamente en Sincronización.


Diferencia teórica:

En CountDownLatch, los subprocesos principales esperan a que otros subprocesos completen su ejecución. En CyclicBarrier, los hilos de los trabajadores se esperan unos a otros para completar su ejecución.

No se puede reutilizar la misma instancia de CountDownLatch una vez que el conteo llega a cero y el pestillo está abierto; por otro lado, CyclicBarrier puede reutilizarse al restablecer la barrera, una vez que se rompe la barrera.

Ejemplo de la vida real: -

CountDownLatch: considere un escenario mundial de TI donde el administrador dividió los módulos entre los equipos de desarrollo (A y B) y desea asignarlo al equipo de control de calidad para realizar pruebas solo cuando los dos equipos completen su tarea.

Aquí el subproceso del administrador funciona como subproceso principal y el equipo de desarrollo trabaja como subproceso de trabajo. El subproceso del administrador espera que el subproceso de los equipos de desarrollo complete su tarea.

CyclicBarrier: considere el mismo escenario del mundo de TI donde el administrador dividió los módulos entre los equipos de desarrollo (A y B). Se va de licencia y le pide a ambos equipos que se esperen mutuamente para completar su tarea respectiva una vez que ambos hayan terminado de asignarlo al equipo de control de calidad para la prueba.

Aquí el subproceso del administrador funciona como subproceso principal y el equipo de desarrollo trabaja como subproceso de trabajo. Los hilos del equipo de desarrollo esperan otros hilos del equipo de desarrollo después de completar su tarea.