Red de conocimiento informático - Aprendizaje de programación - J.U.C|Cola concurrente (CLH)

J.U.C|Cola concurrente (CLH)

En un artículo anterior analizamos los principios de AQS, consulte J.U.C|Taking You Inside AQS.

En este artículo, analizaremos las colas síncronas principales (CLH) en AQS.

Cola síncrona

Una cola bidireccional de primero en entrar, primero en salir. Cada nodo de la cola está esperando a que el nodo anterior libere el estado compartido (bloqueo) para poder hacerlo. ser despertado.

AQS ¿Cómo usarlo?

AQS confía en él para completar la gestión del estado de sincronización. Si el subproceso actual no puede obtener el estado de sincronización, AQS construirá un nodo (Nodo) y agregará la información del estado que el subproceso actual ha estado esperando a la cola de sincronización de CLH, mientras bloquea el subproceso actual, y luego cuando la sincronización Se libera el estado, despierta los primeros nodos (bloqueo justo), intenta obtener el estado de sincronización nuevamente.

¿Cómo es Node?

Diagrama esquemático de la cola de sincronización CLH

El nodo de cola aquí se configura de acuerdo con CAS (se puede garantizar la seguridad del subproceso).

A través de la estructura de la cola de sincronización que se muestra en la figura anterior, podemos analizar fácilmente su operación de entrada. Simplemente apunta la cola (usando CAS para garantizar operaciones atómicas) al nuevo nodo, el anterior del nuevo nodo apunta al último nodo en la cola (el antiguo nodo de cola) y el último nodo del siguiente nodo apunta al nuevo nodo. En la cola original, establezca un enlace. El diagrama puede ayudarlo a comprender.

Código fuente

Podemos entender el código fuente a través de los siguientes dos métodos en AQS

Método addWaiter

Primero, a través de addWaiter ( El método Node node) intenta establecer rápidamente el nodo como nodo de cola; si falla, pasa al método enq (nodo de nodo final)

enq

Asegúrate de pasar " rotar" o morir El bucle agrega nodos al final de la cola y sale del bucle solo cuando el nodo se agrega correctamente; de ​​lo contrario, el nodo permanecerá en la cola. Saldrá del bucle solo después de agregar con éxito el nodo; de lo contrario, continuará el bucle hasta que tenga éxito.

Ambos métodos configuran el nodo de cola a través del método compareAndSetHead(new Node()) para garantizar que la adición de nodos sea atómica (y segura para subprocesos).

La cola de sincronización (CLH) sigue el principio de primero en entrar, primero en salir. El primer nodo es el nodo que obtiene el estado de sincronización. Una vez que el hilo del primer nodo libera el estado de sincronización. despierta su nodo posterior (siguiente). Los nodos posteriores se configuran como el primer nodo después de obtener con éxito el estado de sincronización. Como se muestra en la siguiente figura

La configuración del nodo principal la completa el subproceso que obtiene con éxito el estado de sincronización (la obtención del estado de sincronización la completa CAS. Solo un subproceso puede obtener el estado de sincronización, por lo que el subproceso obtiene el estado de sincronización). No se requiere la operación de configuración del nodo principal para garantizar CAS, solo necesita configurar el nodo principal como el nodo sucesor del nodo principal original y desconectar el siguiente del nodo principal original (esperando el reciclaje de GC). Sólo aplica.

Dicho esto, resumamos que la cola de sincronización es una cola bidireccional FIFO, en la que cada nodo contiene la aplicación, el estado de espera, el nodo predecesor y el sucesor del hilo que no pudo obtener la sincronización. Estado del nodo, tipo de atributo del nodo y descripción del nombre.

Las operaciones entrantes utilizan CAS (seguro para subprocesos) para configurar el nodo de cola, las operaciones de salida son muy simples: apunte el cabezal directamente al nuevo nodo principal y desconecte el nodo principal anterior.