Cola de bloqueo vinculada
LinkedBlockingQueue es una cola de bloqueo de doble extremo ilimitada segura para subprocesos que admite FIFO y LIFO. Podemos revisar las características del LinkedBlockingQueue anterior. Son similares en naturaleza, pero tienen algunas diferencias:
La relación entre Queue y Deque es algo similar a las listas enlazadas individualmente y las listas doblemente enlazadas. La implementación del nodo interno de LinkedBlockingQueue y LinkedBlockingQueue es la diferencia entre listas enlazadas individualmente y listas doblemente enlazadas. Consulte el código fuente para obtener más detalles.
Segundo punto, algunas personas pueden tener algunas preguntas. ¿Cuál es la diferencia entre dos mutex y un mutex? Podemos considerar el siguiente escenario:
El subproceso A primero se une a la cola y luego el subproceso B sale de la cola. Si es LinkedBlockingQueue, el proceso de puesta en cola del subproceso A no ha finalizado (el bloqueo adquirido aún no se ha liberado) y la operación de puesta en cola del subproceso B no se bloqueará (los bloqueos son diferentes). Si es un LinkedBlockingQueue, el subproceso B se bloqueará y esperará a que el subproceso A (mismo bloqueo) complete la operación antes de continuar.
La operación general de LinkedBlockingQueue es adquirir un candado, pero algunas operaciones, como la operación de eliminación, necesitan adquirir dos candados al mismo tiempo, como se explicó anteriormente para LinkedBlockingQueue.
LinkedBlockingQueue es una estructura de lista vinculada única, que solo se puede operar en un extremo. El encabezado es de solo lectura y el final es de solo escritura, por lo que los dos bloqueos son más eficientes. LinkedBlockingDeque es una estructura de lista de doble enlace, ambos extremos se pueden leer y escribir, por lo que solo un bloqueo puede garantizar la atomicidad. Por supuesto, la eficiencia es aún menor.
ArrayBlockingQueue
LinkedBlockingQueue
Pregunta, ¿por qué ArrayBlockingQueue no puede usar dos bloqueos?
Porque después de ser eliminados, los elementos de ArrayBlockingQueue deben avanzar.
LinkedBlockingQueue se implementa internamente con una única lista vinculada. Solo puede tomar elementos del encabezado y agregar elementos del final. Hay bloqueos independientes para agregar elementos y obtener elementos, lo que significa que la lectura y escritura de LinkedBlockingQueue están separadas y las operaciones de lectura y escritura se pueden realizar en paralelo. LinkedBlockingQueue utiliza ReentrantLock para garantizar la seguridad de los subprocesos en situaciones concurrentes.
LinkedBlockingQueue * * * tiene tres constructores, a saber, un constructor sin parámetros, un constructor que puede especificar la capacidad y un constructor que puede penetrar en el contenedor. Si se llama al constructor sin parámetros al crear una instancia, la capacidad predeterminada de LinkedBlockingQueue es un número entero. Es probable que MAX_VALUE conduzca a una situación en la que la cola no esté llena pero la memoria sí (desbordamiento de memoria).
El método size() atravesará toda la cola y la complejidad del tiempo es O (n), por lo que es mejor elegir isEmtpy.
1. Determinar si el elemento está vacío. Si está vacío, lanza una excepción.
2. Bloqueo (bloqueo interrumpible)
3. Determine si la longitud de la cola alcanza la capacidad y espere hasta que se alcance la capacidad.
4. Si la cola no está llena, enqueue() agregará elementos al final de la cola.
5. Suma 1 a la longitud de la cola. En este momento, si la cola no está llena, se llama a la señal para despertar otras colas bloqueadas.
1. Bloqueo (aún ReentrantLock). Tenga en cuenta que el bloqueo y la escritura aquí son dos bloqueos diferentes.
2. Determine si la cola está vacía y espere hasta que esté vacía.
3. Obtener datos mediante el método de eliminación de cola.
3. Compruebe si la cola está vacía después de eliminar el elemento. Si no, active otras colas en espera.
Principio: inserte un elemento al final de la cola y devuelva verdadero si la cola no está llena, luego ejecútelo inmediatamente si la cola está llena, devuelva falso inmediatamente;
Principio: si no hay ningún elemento, devuelve nulo directamente; si hay un elemento, sal del equipo.
1. Diagrama de entrada y salida específico:
La primera mitad de cada nodo en la figura representa los datos encapsulados x, y la segunda mitad representa la siguiente referencia a la que apunta.
1.1, Inicialización
Después de la inicialización, los datos de inicialización están vacíos y tanto el primer nodo como el último nodo son este nodo.
1.2, tras incorporarse al equipo.
1.3, después de que el elemento sea retirado de la cola.
En la superficie, simplemente apunta el siguiente puntero del nodo principal a x1.next para ser eliminado. De hecho, creo que esto es completamente posible, pero lo que jdk realmente elimina es el nodo principal original. El nodo principal que se ve arriba es el nodo x1 que acaba de ser retirado de la cola, pero su valor está vacío.
2. Comparación de tres tipos de equipos:
3.