java multithreading synchronization queue

Java: ArrayBlockingQueue vs. LinkedBlockingQueue



multithreading synchronization (2)

Creo que, en la mayoría de los casos, ArrayBlockingQueue tendrá un mejor rendimiento que LinkedBlockingQueue . Sin embargo, ese es el caso cuando siempre hay espacio suficiente en el conjunto ... Si se llena, no es muy predecible si funcionará tan bien, ya que bloqueará el hilo que está tratando de insertar datos en la cola. .

Entonces, mi pregunta es: ¿hay alguna implementación intermedia de BlockingQueue ? Digamos, una ArrayListBlockingQueue o una BucketListBlockingQueue ? ¿Algo así como una lista de matrices, para que la cola pueda aumentar su capacidad de forma dinámica, a la vez que tenga un beneficio razonable al utilizar una matriz para almacenar datos en última instancia?


1. LinkedBlockingQueue (Implementación de LinkedList pero no exactamente Implementación JDK de LinkedList Utiliza nodo de clase interna estática para mantener enlaces entre elementos)

Constructor for LinkedBlockingQueue public LinkedBlockingQueue(int capacity) { if (capacity < = 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node< E >(null); // Maintains a underlying linkedlist. ( Use when size is not known ) }

Clase de nodo utilizada para mantener enlaces

static class Node<E> { E item; Node<E> next; Node(E x) { item = x; } }

2. ArrayBlockingQueue (Implementación de matriz)

Constructor para ArrayBlockingQueue

public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity < = 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; // Maintains a underlying array lock = new ReentrantLock(fair); notEmpty = lock.newCondition(); notFull = lock.newCondition(); }

En mi opinión, la mayor diferencia entre ArrayBlockingQueue y LinkedBlockingQueue es claro desde el constructor, uno tiene la estructura de datos subyacente Array y otra linkedList .

ArrayBlockingQueue utiliza el algoritmo de condición de doble bloqueo único y LinkedBlockingQueue es una variante del algoritmo de "dos cola de bloqueo" y tiene 2 condiciones de 2 bloqueos (takeLock, putLock)

Hasta ahora he dado una comparación entre estas 2 implementaciones. Volviendo a la pregunta original, se hizo una pregunta similar en la lista de correo de concurrencia en este documento. Lea habla sobre DynamicArrayBlockingQueue, que es la implementación proporcionada por Dawid Kurzyniec.


Mis 2 centavos:

Para empezar, la conclusión aquí es que realmente no le importa la diferencia aquí, porque incluso cuando está utilizando una LinkedBlockingQueue simple, el rendimiento es lo suficientemente bueno cuando está entregando algunos sistemas de nivel micro-segundo. Entonces, la diferencia de rendimiento aquí no es tan buena.

Si está escribiendo un sistema de alto rendimiento de misión crítica y está utilizando colas para pasar mensajes entre hilos, siempre puede estimar el tamaño de cola requerido por [Tamaño de cola] = [Retardo máximo aceptable] * [Velocidad máxima de mensaje]. Cualquier cosa que pueda crecer más allá de esa capacidad significa que usted sufre un problema de consumo lento. En una aplicación de misión crítica, dicha demora significa que su sistema no está funcionando correctamente. Algún proceso manual puede ser necesario para asegurarse de que el sistema se está ejecutando correctamente.

En caso de que su sistema no sea crítico para la misión, simplemente puede pausar (bloquear) al editor hasta que haya algunos consumidores disponibles.