Red de conocimiento informático - Aprendizaje de programación - ¿Cuáles son las diferencias entre colas con bloqueo, colas sin bloqueo y colas ordinarias en Java?

¿Cuáles son las diferencias entre colas con bloqueo, colas sin bloqueo y colas ordinarias en Java?

La diferencia entre una cola de bloqueo y una cola normal es que cuando la cola está vacía, se bloqueará la operación de obtener elementos de la cola; cuando la cola esté llena, se bloqueará la operación de agregar elementos a la cola; Un hilo que intenta obtener un elemento de una cola de bloqueo vacía será bloqueado hasta que otro hilo inserte un nuevo elemento en la cola vacía. Del mismo modo, un hilo que intenta agregar un nuevo elemento a una cola de bloqueo que está llena se bloqueará hasta que otro hilo libere la cola nuevamente, por ejemplo eliminando uno o más elementos de la cola o limpiando la cola por completo.

1.ArrayDeque, cola de matriz de doble extremo

2. PriorityQueue, cola de prioridad

3. ConcurrentLinkedQueue, cola concurrente basada en lista vinculada

4. DelayQueue, (cola de bloqueo retardado) (la cola de bloqueo implementa la interfaz BlockingQueue)

5.ArrayBlockingQueue, (cola de bloqueo concurrente basada en matrices)

6.LinkedBlockingDeque, (Cola de bloqueo de doble extremo primero en entrar, primero en salir basada en la lista vinculada)

8.PriorityBlockingQueue, (cola de bloqueo ilimitada con prioridad)

9.SynchronousQueue, (bloqueo concurrente cola basada en lista enlazada)

10.SynchronousQueue, (cola de bloqueo concurrente basada en lista enlazada)

11.SynchronousQueue, (cola de bloqueo concurrente basada en lista enlazada SynchronousQueue (bloqueo sincrónico concurrente cola)

Cola de bloqueo y patrón productor-consumidor

La cola de bloqueo proporciona métodos de entrada y recepción de bloqueo, que son equivalentes a cotizaciones cronometradas y sondeo. Si la cola está llena, se utiliza el método de venta. se bloqueará hasta que aparezca el espacio disponible; si la cola está vacía, el método take se bloqueará hasta que aparezca un elemento disponible; la longitud de la cola puede ser limitada o infinita, la cola infinita nunca se llenará, por lo que su método put nunca se llenará; block .

Las colas de bloqueo admiten el patrón de diseño productor-consumidor. El patrón de diseño productor-consumidor separa "producir productos" y "consumir productos". procesamiento posterior El patrón productor-consumidor simplifica el proceso de desarrollo porque elimina la necesidad de que el código del productor y del consumidor dependan entre sí. Los productores producen y consumen datos a velocidades diferentes o cambiantes. El patrón productor-consumidor separa estas actividades. gestión de carga de trabajo.

El diseño productor-consumidor gira en torno al bloqueo de colas donde el productor coloca datos en la cola y los pone a disposición, y el consumidor toma los datos de la cola cuando está listo para comportarse apropiadamente. El productor no necesita saber la provincia o el número de consumidores, ni siquiera si hay consumidores; simplemente colocan los datos en la cola. Del mismo modo, el consumidor no necesita saber quién es el productor ni quién establece el productor. BlockingQueue puede utilizar cualquier número de productores y consumidores, lo que simplifica la implementación del diseño de productor-consumidor. El diseño de productor-consumidor más común combina un grupo de subprocesos y una cola de trabajo.

Las colas de bloqueo simplifican la codificación del consumidor porque la cola de trabajo se bloquea hasta que haya datos disponibles. Si el productor no puede generar trabajo lo suficientemente rápido como para mantener ocupado al consumidor, éste debe esperar a que haya trabajo disponible. Además, la función de bloqueo del método put también simplifica enormemente la codificación del productor; si se utiliza una cola limitada, cuando la cola se llena, el productor se bloqueará y no podrá generar más trabajo temporalmente, proporcionando así tiempo a los consumidores. para ponerse al día.

Las colas limitadas son poderosas herramientas de administración de recursos para crear aplicaciones confiables: suprimen la actividad amenazante que podría generar demasiado trabajo, lo que hace que su programa sea más sólido frente a la sobrecarga.

Aunque el patrón productor-consumidor separa el código del productor y del consumidor entre sí, su comportamiento todavía está indirectamente acoplado a través de colas de disfrute

La biblioteca de clases contiene una gran cantidad de BlockingQueue implementaciones, donde LinkedBlockingQueue y ArrayBlockingQueue son colas de primero en entrar, primero en salir, similares a LinkedList y ArrayList, pero tienen un mejor rendimiento de concurrencia que las listas sincronizadas. PriorityBlockingQueue es una cola ordenada por prioridad. Esta PriorityBolckingQueue es muy útil cuando no desea procesar elementos de acuerdo con la propiedad primero en entrar, primero en salir. Al igual que otros contenedores de clasificación, PriorityBlockingQueue puede comparar los elementos en su orden natural (si implementan Comparable), o pueden ordenarse mediante un comparador.

La última implementación de BlockingQueue es SynchronousQueue, que en realidad no es una cola porque no mantiene ningún espacio de almacenamiento para los elementos de la cola. Sin embargo, mantiene una lista de subprocesos de la cola que esperan agregar (poner en cola) elementos o eliminar (quitar de la cola) elementos de la cola. Debido a que SynchronousQueue no tiene capacidad de almacenamiento, las transferencias y tomas siempre se bloquean a menos que otro subproceso esté listo para participar en la transferencia. Las colas como SynchronousQueue solo son adecuadas cuando hay suficientes consumidores y siempre están listos para la siguiente tarea.

Algoritmo sin bloqueo

Los algoritmos basados ​​en bloqueo tienen un cierto riesgo de falla en la actividad. Si un subproceso se retrasa debido a un bloqueo de E/S, errores de página u otros motivos mientras se mantiene el bloqueo, es probable que todos los subprocesos no puedan avanzar.

Si la falla o suspensión de un subproceso no afecta la falla o suspensión de otros subprocesos, entonces este algoritmo se convierte en un algoritmo sin bloqueo, si en cada paso del algoritmo, algunos subprocesos pueden continuar ejecutándose, entonces este algoritmo se llama algoritmo sin bloqueo. Los algoritmos que utilizan CAS para coordinar entre subprocesos, si se construyen correctamente, no bloquean ni bloquean. El CAS no competitivo siempre tiene éxito; si varios subprocesos compiten con CAS, un subproceso siempre ganará y seguirá adelante. Los algoritmos sin bloqueo son "inmunes" a los interbloqueos y las inversiones de prioridad (pero pueden sufrir inanición y bloqueo activo ya que se permite el reingreso).

Los algoritmos sin bloqueo reemplazan los bloqueos mediante el uso de primitivas de concurrencia de bajo nivel, como comparar e intercambiar. Las clases de variables atómicas proporcionan a los usuarios estas primitivas de bajo nivel y también se pueden utilizar como "mejores variables volátiles" y proporcionan actualizaciones atómicas para clases enteras y referencias de objetos.