14 super resumen de contenedores concurrentes de Java

Independientemente de la concurrencia de subprocesos múltiples, las clases de contenedor generalmente usan clases inseguras para subprocesos como ArrayList y HashMap, que son más eficientes. En escenarios de simultaneidad, a menudo se utilizan clases de contenedor seguras para subprocesos como ConcurrentHashMap y ArrayBlockingQueue. Aunque se sacrifica algo de eficiencia, son seguras.

Los contenedores seguros para subprocesos mencionados anteriormente están todos en el paquete java.util.concurrent. Hay muchos contenedores simultáneos en este paquete. Hoy en día, todos resultaron ser útiles.

Simplemente haga una breve introducción y luego exploraremos en profundidad más adelante.

Introducción a los contenedores concurrentes

  1. ConcurrentHashMap: ConcurrentHashMap
  2. CopyOnWriteArrayList: ArrayList concurrente
  3. CopyOnWriteArraySet: Conjunto concurrente
  4. ConcurrentLinkedQueue: cola concurrente (basada en la lista vinculada)
  5. ConcurrentLinkedDeque: cola concurrente (basada en una lista doblemente vinculada)
  6. ConcurrentSkipListMap: mapa concurrente basado en la tabla de omisión
  7. ConcurrentSkipListSet: Conjunto concurrente basado en la tabla de omisión
  8. ArrayBlockingQueue: cola de bloqueo (basada en la matriz)
  9. LinkedBlockingQueue: cola de bloqueo (según la lista vinculada)
  10. LinkedBlockingDeque: Cola de bloqueo (basada en una lista doblemente enlazada)
  11. PriorityBlockingQueue: cola de prioridad segura para subprocesos
  12. SynchronousQueue: lee y escribe colas emparejadas
  13. LinkedTransferQueue: cola de intercambio de datos basada en una lista vinculada
  14. DelayQueue: cola de retardo

1. ConcurrentHashMap ConcurrentHashMap ConcurrentHashMap

Uno de los contenedores concurrentes más comunes se puede utilizar como caché en escenarios concurrentes. La capa inferior sigue siendo una tabla hash, pero ha cambiado mucho en JAVA 8. JAVA 7 y JAVA 8 usan más versiones, por lo que a menudo comparan la implementación de estas dos versiones (como Interview).

Una gran diferencia es que en JAVA 7, los bloqueos segmentados se usan para reducir la competencia de bloqueos, y los bloqueos segmentados se abandonan en JAVA 8, y se usa CAS (un bloqueo optimista) y, al mismo tiempo, para evitar que el conflicto hash se degenere en una lista vinculada (en caso de conflicto, se generará una lista vinculada en esta posición, y los objetos con el mismo valor hash se vincularán entre sí), y se convertirán en un árbol rojo-negro después de la longitud del La lista enlazada alcanza el umbral (8) (en comparación con la lista enlazada, la eficiencia de consulta del árbol es más estable).

2. CopyOnWriteArrayList versión concurrente de ArrayList

En la versión concurrente de ArrayList, la estructura subyacente también es una matriz. La diferencia con ArrayList es que se crea una nueva matriz al agregar y eliminar elementos, agregar o excluir objetos especificados en la nueva matriz y finalmente reemplazar la matriz original con el nueva matriz.

Escenarios aplicables: dado que la operación de lectura no está bloqueada y la operación de escritura (agregar, eliminar, modificar) está bloqueada, es adecuada para escenarios donde se realizan más lecturas y menos escrituras.

Limitaciones: Dado que no hay bloqueo durante la lectura (la eficiencia de lectura es alta, al igual que una ArrayList normal), la copia actual de la lectura, por lo que se pueden leer datos sucios. Si le importa, se recomienda no hacerlo.

Eche un vistazo al código fuente y sienta:

14 super resumen de contenedores concurrentes de Java


3. Conjunto concurrente CopyOnWriteArraySet

Implementación basada en CopyOnWriteArrayList (que contiene una variable miembro CopyOnWriteArrayList), es decir, la capa inferior es un array, lo que significa que cada vez que add tiene que atravesar toda la colección para saber si existe, y necesita ser insertada (bloqueada ) cuando no existe.

Escenario aplicable: agregue uno en el escenario aplicable de CopyOnWriteArrayList, y el conjunto no debe ser demasiado grande (no puede afectar a todos los recorridos).

4.ConcurrentLinkedQueue cola concurrente (basada en la lista vinculada)

Según la cola simultánea implementada por la lista vinculada, se utiliza el bloqueo optimista (CAS) para garantizar la seguridad de los subprocesos. Debido a que la estructura de datos es una lista vinculada, teóricamente no hay límite de tamaño de cola, lo que significa que la adición de datos debe realizarse correctamente.

5.ConcurrentLinkedDeque cola concurrente (basada en una lista doblemente vinculada)

Las colas concurrentes basadas en listas doblemente enlazadas pueden operar en la cabeza y la cola por separado, por lo que además del primero en entrar, primero en salir (FIFO), también se puede usar primero en entrar, último en salir (FILO). llamarse pila si es el primero en entrar, el último en salir.

6. ConcurrentSkipListMap basado en el mapa de concurrencia de la tabla de omisión

SkipList es una lista de omisión, una lista de omisión es una estructura de datos de espacio por tiempo.A través de datos redundantes, la lista vinculada se indexa capa por capa para lograr un efecto de búsqueda binaria similar.

14 super resumen de contenedores concurrentes de Java


7. ConcurrentSkipListSet Conjunto concurrente basado en la tabla de omisión

Similar a la relación entre HashSet y HashMap, ConcurrentSkipListSet contiene un ConcurrentSkipListMap, por lo que no entraré en detalles.

8. Cola de bloqueo de ArrayBlockingQueue (basada en la matriz)

Cola bloqueable basada en la implementación de la matriz, el tamaño de la matriz debe especificarse al construir, y si la matriz está llena cuando coloca algo en ella, se bloqueará hasta que haya una posición (también se admiten el retorno directo y el tiempo de espera de espera), y la seguridad del hilo está garantizada a través de un candado ReentrantLock.

Tome un ejemplo con la operación de oferta:

A primera vista, puede parecer un poco confuso. Leer y escribir son el mismo bloqueo. Si resulta que está vacío cuando llega un hilo de lectura, ¿no estará bloqueado todo el tiempo?

La respuesta está en notEmpty y notFull Estas dos pequeñas cosas de lock le dan a la cerradura una función similar a sincronizada + esperar + notificar.

9.LinkedBlockingQueue bloqueo de cola (basado en la lista enlazada)

La cola de bloqueo implementada en función de la lista vinculada tiene un límite de capacidad más que el ConcurrentLinkedQueue sin bloqueo. Si no se establece, se establece de forma predeterminada en el valor máximo de int.

10.LinkedBlockingDeque cola de bloqueo (basada en una lista doblemente enlazada)

Similar a LinkedBlockingQueue, pero proporciona operaciones únicas para listas doblemente enlazadas.

11.PriorityBlockingQueue cola de prioridad segura para subprocesos

Se puede pasar un comparador durante la construcción, que se puede considerar como los elementos colocados se clasificarán y luego se consumirán en orden durante la lectura. Es posible que algunos elementos de baja prioridad no se consuman durante mucho tiempo, porque los elementos de mayor prioridad están apareciendo constantemente.

12.SynchronousQueue Queue para intercambio de sincronización de datos

Una cola falsa, debido a que en realidad no tiene espacio para almacenar elementos, cada operación de inserción debe tener una operación de recuperación correspondiente y no se puede continuar colocando cuando no se recupera.

Un ejemplo sencillo para sentir:

Se puede ver que el hilo de escritura no tiene sueño, se puede decir que pone las cosas en la cola con toda su fuerza, mientras que el hilo de lectura está muy inactivo y duerme un rato después de leer. El resultado de salida es que las operaciones de lectura y escritura aparecen en pares.

Un escenario de uso en JAVA es
Executors.newCachedThreadPool (), que crea un grupo de subprocesos de caché.

13.LinkedTransferQueue cola de intercambio de datos basada en la lista vinculada

Se implementa la interfaz TransferQueue, y cuando se coloca un elemento a través del método de transferencia, si se encuentra que un hilo está bloqueado al buscar un elemento, el elemento se entregará directamente al hilo en espera. Si nadie está esperando consumir, el elemento se colocará al final de la cola y este método se bloqueará hasta que alguien lea el elemento. Es un poco similar a SynchronousQueue, pero más poderoso que él.

14.DelayQueue cola de retardo

El consumidor puede eliminar los elementos puestos en la cola después de un retraso especificado, y los elementos deben implementar la interfaz retardada.

para resumir

Lo anterior introdujo brevemente algunas clases de contenedores en el paquete concurrente de JAVA. Sabiendo estas cosas, cuando se encuentre con un escenario adecuado, puede recordar que hay algo listo para usar que se puede usar. Si quiere saber por qué, debe explorar más en el seguimiento.


Supongo que te gusta

Origin blog.51cto.com/15128443/2677960
Recomendado
Clasificación