Varias colas de bloqueo en Java
La BlockingQueue
interfaz en Java es una cola de acceso segura para subprocesos, adecuada para escenarios de aplicaciones de productores y consumidores, y admite dos operaciones adicionales:
- El hilo del productor continuará poniendo datos en la cola de bloqueo hasta que la cola esté llena. Cuando la cola está llena, el subproceso productor se bloquea y espera a que el subproceso consumidor obtenga datos.
- El hilo del consumidor continuará obteniendo datos de la cola de bloqueo hasta que la cola esté vacía. Una vez que la cola está vacía, el hilo del consumidor se bloquea esperando que el hilo del productor coloque datos.
Interfaz BlockingQueue
BlockingQueue
Proporciona cuatro métodos de procesamiento diferentes.
Lanzar una excepción | Devolver valor especial | Sigue bloqueando | Salida del tiempo de espera | |
---|---|---|---|---|
Insertar método | añadir (o) | oferta (o) | poner (o) | oferta (o, tiempo de espera, unidad de tiempo) |
Método de eliminación | quitar (o) | encuesta() | tomar (o) | encuesta (o, tiempo de espera, unidad de tiempo) |
Método de inspección | elemento() | ojeada() | - | - |
- Lanza una excepción :
- agregar: Al insertar datos, si la cola de bloqueo está llena, se
IllegalStateException
lanzará una excepción ; de lo contrario, la inserción regresará correctamentetrue
. Cuando se utiliza una cola de capacidad limitada para bloquear la cola, se recomienda utilizar eloffer
método.IllegalStateException
- si el elemento no se puede agregar en este momento debido a restricciones de capacidadClassCastException
- si la clase del elemento especificado impide que se agregue a esta colaNullPointerException
- si el elemento especificado es nuloIllegalArgumentException
- si alguna propiedad del elemento especificado impide que se agregue a esta cola
- eliminar: Al eliminar datos, si hay estos datos en la cola, la eliminación se devolverá correctamente
true
, de lo contrario, se devolveráfalse
. Si contiene uno o más objetos, solo elimine uno y regresetrue
. Nota:remove(o)
esBlockingQueue
el métodoremove()
de laQueue
interfaz , es el método de la interfaz. - elemento: si la cola está vacía, se lanza una excepción
NoSuchElementException
. Si la cola no está vacía, el jefe de los datos de consulta devuelve cola, pero no elimina los datos , esto es diferente de laremove()
,element
mismaQueue
método de interfaz.
- agregar: Al insertar datos, si la cola de bloqueo está llena, se
- Devuelve un valor especial :
- oferta: al insertar datos, si la cola de bloqueo no está llena, entonces la inserción es exitosa y regresa
true
, de lo contrario se devuelvefalse
. Cuando se utiliza una cola de bloqueo limitada (cola de capacidad limitada), se recomienda utilizar eloffer
método, no eladd
método que genera una excepción . - encuesta: este método es una
Queue
interfaz. Si la cola no está vacía, consulte, elimine y devuelva el elemento principal de la cola. Si la cola está vacía, regresenull
. - peek: este método es una
Queue
interfaz. Si la cola está vacía, regresanull
, que es diferentepoll
. Si la cola no está vacía, la consulta devuelve los datos al principio de la cola, pero no elimina los datos, que es diferenteremove()
.
- oferta: al insertar datos, si la cola de bloqueo no está llena, entonces la inserción es exitosa y regresa
- Siempre bloqueado :
- put: Al insertar datos, si la cola está llena, la cola de espera de bloqueo está disponible, y si se interrumpe durante el período de espera, se lanzará
InterruptedException
. - tomar: Consulta, elimina y devuelve el elemento principal de la cola. Si la cola está vacía, entonces la cola de espera de bloqueo está disponible. Si se interrumpe durante el período de espera, lanza
InterruptedException
.
- put: Al insertar datos, si la cola está llena, la cola de espera de bloqueo está disponible, y si se interrumpe durante el período de espera, se lanzará
- Salir después del tiempo de espera :
- oferta: al insertar datos, si la cola está llena, entonces bloquee el tiempo especificado esperando que la cola esté disponible, y si se interrumpe durante el período de espera, entonces tírela
InterruptedException
. Si la inserción es exitosa, regresetrue
, si la cola aún no está disponible después del tiempo especificado, regresefalse
. - poll: Consulta, borra y devuelve el elemento de cabecera de la cola. Si la cola está vacía, se bloqueará por el tiempo especificado y esperará a que la cola esté disponible. Si se interrumpe durante el período de espera, se lanzará
InterruptedException
. Si la eliminación se realiza correctamente, devuelva el elemento principal de la cola, si la cola aún no está disponible después del tiempo especificado, vuelvanull
.
- oferta: al insertar datos, si la cola está llena, entonces bloquee el tiempo especificado esperando que la cola esté disponible, y si se interrumpe durante el período de espera, entonces tírela
Queue
No puede insertar nulo en la cola, de lo contrario se lanzará NullPointerException
.
Cola de bloqueo en Java
JDK7 proporciona 7 colas de bloqueo. Respectivamente son
- ArrayBlockingQueue: una cola de bloqueo limitada compuesta por una estructura de matriz.
- LinkedBlockingQueue: una cola de bloqueo limitada compuesta por una estructura de lista enlazada.
- PriorityBlockingQueue: una cola de bloqueo ilimitada que admite la clasificación de prioridad.
- DelayQueue: una cola de bloqueo ilimitada implementada utilizando colas de prioridad.
- SynchronousQueue: una cola de bloqueo que no almacena elementos.
- LinkedTransferQueue: una cola de bloqueo ilimitada compuesta por una estructura de lista enlazada.
- LinkedBlockingDeque: Una cola de bloqueo bidireccional compuesta por una estructura de lista enlazada.
ArrayBlockingQueue
ArrayBlockingQueue
Es una cola de bloqueo limitada primero en entrar, primero en salir (FIFO) basada en matrices.
- Al crear una cola, debe especificar la capacidad de la cola (capacidad), es decir, el tamaño de la matriz.
- Al crear una cola, puede pasar
Collection
para inicializar los elementos de la cola. - Una vez que se crea la cola, la capacidad de la cola no se puede cambiar.
- La cola admite el modo justo y el modo injusto, y el modo predeterminado es el modo injusto.
- Solo hay un bloqueo en la cola, el bloqueo de escritura y el bloqueo de lectura no están separados y el control de concurrencia adopta el algoritmo clásico de dos condiciones (
notEmpty
,notFull
).
LinkedBlockingQueue
LinkedBlockingQueue
Es una cola de bloqueo limitada opcionalmente basada en un primero en entrar, primero en salir (FIFO) de nodos vinculados.
- Al crear una cola, para evitar gastos generales adicionales, puede especificar la capacidad de la cola; si no especifica la capacidad de la cola, la capacidad de la cola predeterminada es
Integer.MAX_VALUE
. - Al crear una cola, puede pasar
Collection
para inicializar los elementos de la cola. En este momento, no puede especificar la capacidad de la cola. El valor predeterminado esInteger.MAX_VALUE
. - Cola de
count
número de un elemento de la cola que se utiliza actualmenteAtomicInteger
para prevenirput
ytake
competencia. - La
ArrayBlockingQueue
diferencia esLinkedBlockingQueue
que hay dos bloqueos en la cola, el bloqueo de lectura y el bloqueo de escritura están separados. - Cuando está en uso
LinkedBlockingQueue
, si el tamaño de la cola es el valor predeterminado y la velocidad de producción es mayor que la velocidad de consumo, se puede producir un desbordamiento de la memoria. LinkedBlockingQueue
En teoría,ArrayBlockingQueue
tiene un rendimiento más alto, pero en la mayoría de los escenarios de aplicación práctica, no funciona bien.
PriorityBlockingQueue
PriorityBlockingQueue
Es una cola de bloqueo ilimitada basada en matriz que admite prioridad. La estructura de datos de esta cola es un montón.
- Al crear una cola, si especifica la capacidad inicial (initialCapacity), la capacidad inicial predeterminada
DEFAULT_INITIAL_CAPACITY
es 11. - Al crear una cola, puede especificar la capacidad inicial de la cola (initialCapacity), no la capacidad de la cola (capacidad).
PriorityBlockingQueue
Lo ilimitado (ilimitado) relativo alLinkedBlockingQueue
limitado opcional (limitado opcionalmente), ilimitado significa que la capacidad máxima de la cola no se puede especificar al crear la cola, no quePriorityBlockingQueue
no sea ilimitada.LinkedBlockingQueue
El valor predeterminado (tenga en cuenta que esto se refiere a la capacidad predeterminada, es decir, puede especificarInteger.MAX_VALUE
un valor mayor que ) la capacidad máxima esInteger.MAX_VALUE
yPriorityBlockingQueue
la capacidad máxima esMAX_ARRAY_SIZE=Integer.MAX_VALUE-8
.PriorityBlockingQueue
Otro significado de ilimitado es que el subproceso productor no se bloqueará porque la cola está llena, porque la cola no está limitada y no existe la capacidad total.offer(E e, long timeout, TimeUnit unit)
Los dos últimos parámetros no tienen efecto, mirando el código fuente, se encuentra que la implementación del método se llama directamenteoffer(e)
. Pero cuando la cola está vacía,take
todavía se bloqueará.offer(e)
Nunca regresefalse
,offer(E e, long timeout, TimeUnit unit)
nunca regresefalse
o bloquee.PriorityBlockingQueue
La cola se implementa a través de una matriz. Cuando la matriz original está llena, la capacidad de la cola se expande al copiar la matriz. Si la capacidad de la matriz recién expandida excedeMAX_ARRAY_SIZE
, se lanzaráOutOfMemoryError
una excepción.- De forma predeterminada, los elementos se organizan en orden natural y el comparador también puede especificar las reglas de clasificación de los elementos. Los elementos están dispuestos en orden ascendente.
DelayQueue
DelayQueue
Se basa en la PriorityQueue
implementación de una cola de bloqueo que soporta la adquisición retardada de elementos.
DelayQueue
Los objetos almacenados en deben implementar laDelayed
interfaz.- Si no hay ningún elemento de vencimiento, entonces no hay ninguno
head
y elpoll
método devuelve nulo. - Cuando el
getDelay(TimeUnit.NANOSECONDS)
valor de retorno de un elemento es menor o igual a 0, el elemento caduca. - Aunque los elementos no vencidos no se pueden usar
take
nipoll
eliminar, estos elementos no vencidos se tratan igual que los elementos vencidos. Por ejemplo,size
la cantidad devuelta por el método es la suma de los elementos vencidos y los no vencidos.
DelayQueue
Escenarios aplicables:
- Cierre los enlaces inactivos. Hay muchos enlaces inactivos en el servidor, después de un cierto período de tiempo, ciérrelos.
- Elimina la caché caducada. Después de un cierto período de tiempo, elimine algunos objetos almacenados en caché.
- Procesamiento del tiempo de espera de la tarea. En la interacción de respuesta de solicitud de ventana deslizante del protocolo de red, procesamiento de solicitudes que no responden al tiempo de espera.
- Después de 60 segundos después de que se genera el pedido, se enviará una notificación por SMS al usuario.
- 15 minutos después de que se realiza el pedido, si el usuario no paga, el pedido se cierra.
A través de los varios ejemplos de escenas anteriores, se puede ver que es DelayQueue
adecuado para realizar ciertos procesos comerciales después de un cierto período de tiempo .
SynchronousQueue
SynchronousQueue
No hay búfer de datos BlockingQueue
.
- La inserción de un subproceso debe esperar a que se complete la operación de eliminación de otro subproceso, y viceversa.
SynchronousQueue
Adecuado para diseños de transferencia, es decir, un escenario en el que un objeto que se ejecuta en un subproceso necesita pasar cierta información, tareas o eventos a un objeto que se ejecuta en otro subproceso.SynchronousQueue
Apoye modelos justos e injustos.- No se puede hacer en una cola sincronizada
peek
, porque el elemento solo existe cuando se intenta eliminarlo. - La cola no se puede iterar porque no hay elementos disponibles para la iteración.
Executors.newCachedThreadPool()
SynchronousQueue
La cola se usa en .
LinkedTransferQueue
LinkedTransferQueue
Es una cola de bloqueo ilimitada basada en nodos vinculados.
- Cola ilimitada (
Integer.MAX_VALUE
), la cola de entrada y salida adopta el principio FIFO (primero en entrar, primero en salir). - El productor bloqueará hasta que los elementos agregados a la cola sean consumidos por un determinado consumidor. Se utiliza principalmente para la transmisión de mensajes entre hilos, que
SynchronousQueue
es muy similar peroSynchronousQueue
mejor que eso. LinkedTransferQueue
Puede usarBlockingQueue
elput
método para realizar operaciones regulares de adición de elementos o puede usar eltransfer
método para bloquear la adición.- En comparación con la
SynchronousQueue
flexibilidad, la longitud de la cola es distinta de cero y pueden coexistir elementos de inserción de bloqueo e inserción de no bloqueo. - Si actualmente hay un consumidor esperando recibir un elemento (cuando el consumidor usa un
take()
método o un método con un límite de tiempopoll()
), eltransfer
método puede transferir inmediatamente el elemento pasado por el productor al consumidor. Si no hay ningún consumidor esperando recibir el elemento, eltransfer
método almacenará el elemento en eltail
nodo de la cola y esperará hasta que el consumidor lo consuma antes de regresar.
LinkedBlockingDeque
LinkedBlockingDueue
Es una cola de bloqueo bidireccional limitada opcionalmente basada en nodos vinculados.
- La cola de bloqueo admite los modos de operación FIFO y FILO, es decir, operaciones simultáneas (insertar / eliminar) desde el principio y el final de la cola.
- La cola de bloqueo es segura para subprocesos.
- Al inicializar LinkedBlockingDeque, puede configurar la capacidad para evitar su expansión excesiva.
- La cola de bloqueo bidireccional se puede utilizar en el modo "robo de trabajo" ( robo de trabajo ).