Comprensión profunda del análisis del código fuente ReentrantLock del bloqueo exclusivo de AQS

Monitor: la filosofía de diseño de la sincronización de Java

  • Monitorear: se refiere a la gestión de variables compartidas y el proceso de operación de variables compartidas, para que puedan soportar la concurrencia.
  • Exclusión mutua: solo un hilo puede acceder a recursos compartidos al mismo tiempo;
  • Sincronización: cómo los hilos se comunican y colaboran.

modelo mesa

En la historia del desarrollo de procesos de tubos, han aparecido sucesivamente tres modelos diferentes de procesos de tubos: el modelo Hasen, el modelo Hoare y el modelo MESA. Lo que ahora se utiliza mucho es el modelo MESA .
Insertar descripción de la imagen aquí
En el monitor se introduce el concepto de variables de condición , y cada variable de condición corresponde a una cola de espera. La función de la cola de espera de variables de condición es resolver el problema de sincronización entre subprocesos.

Hay dos implementaciones de monitores en Java.

  • Uno es el mecanismo de monitor basado en objetos, que se utiliza para implementar bloqueos integrados sincronizados.
  • Uno es el sincronizador de cola abstracto AQS, que se utiliza para implementar el mecanismo de bloqueo en el paquete JUC.

Análisis de principios de AQS

¿Qué es AQS?

  La mayoría de las implementaciones de sincronizadores en el paquete java.util.concurrent giran en torno a comportamientos básicos comunes, como colas de espera, colas condicionales, adquisiciones exclusivas, adquisiciones compartidas, etc., y la abstracción de estos comportamientos se basa en AbstractQueuedSynchronizer (AQS para abreviar ) . , AQS es un marco de sincronización abstracto que se puede utilizar para implementar un sincronizador dependiente del estado.

La mayoría de los sincronizadores proporcionados en el JDK, como Lock, Latch, Barrier, etc., se implementan en función del marco AQS:

  • Generalmente, AQS se hereda a través de una clase interna Sync.
  • Asigne todas las llamadas del sincronizador al método correspondiente de sincronización

Características de AQS:

  • bloquear cola de espera
  • compartido/exclusivo
  • justo injusto
  • reentrante
  • Permitir interrupciones

Estructura central de AQS

El atributo de mantenimiento interno de AQS volatile int state
state representa el estado disponible del recurso

El estado tiene tres métodos de acceso :

  • obtenerEstado()
  • establecerEstado()
  • compararAndSetState()

Se definen dos métodos de acceso a recursos:

  • Exclusivo-exclusivo, solo se puede ejecutar un hilo, como ReentrantLock
  • Compartir: compartir, se pueden ejecutar varios subprocesos al mismo tiempo, como Semaphore/CountDownLatch

AQS implementa principalmente los siguientes métodos:

  • isHeldExclusively(): si el subproceso ocupa recursos exclusivamente. Sólo cuando se utiliza la condición es necesario implementarla.
  • tryAcquire(int): modo exclusivo. Intente obtener el recurso y devuelva verdadero si tiene éxito y falso si falla.
  • tryRelease(int): modo exclusivo. Intente liberar el recurso y devuelva verdadero si tiene éxito y falso si falla.
  • tryAcquireShared(int): método para compartir. Intenta conseguir recursos. Un número negativo indica error; 0 indica éxito, pero no quedan recursos disponibles; un número positivo indica éxito y quedan recursos.
  • tryReleaseShared(int): modo de compartir. Intente liberar el recurso. Si se permite que el nodo de espera posterior se despierte después de la liberación, devuelve verdadero; de lo contrario, devuelve falso.

AQS define dos colas

  • Cola de espera síncrona: se utiliza principalmente para mantener subprocesos que se unen a la cola cuando falla la adquisición de bloqueos.
  • Cola de espera condicional: cuando se llama await (), el bloqueo se liberará y luego el subproceso se unirá a la cola condicional. Cuando se llame a signal () para despertar, el nodo del subproceso en la cola condicional se moverá a la sincronización cola, esperando obtener el bloqueo nuevamente.

AQS define 5 estados de nodos en la cola:

  • El valor es 0, estado de inicialización, lo que indica que el nodo actual está en la cola de sincronización, esperando adquirir el bloqueo.
  • CANCELADO, el valor es 1, lo que indica que el hilo actual está cancelado;
  • SEÑAL, el valor es -1, lo que indica que los subprocesos contenidos en los nodos sucesores del nodo actual deben ejecutarse, es decir, desestacionarse;
  • CONDICIÓN, el valor es -2, lo que indica que el nodo actual está esperando la condición, es decir, en la cola de condiciones;
  • PROPAGAR, el valor es -3, lo que indica que adquirirShared posterior se puede ejecutar en el escenario actual;
    Insertar descripción de la imagen aquí

Cola de espera sincrónica

La cola de espera síncrona en AQS también se llama cola CLH. La cola CLH es una cola basada en una estructura de datos de lista doblemente enlazada inventada por Craig, Landin y Hagersten. Es una cola de espera de subprocesos FIFO primero en entrar, primero en salir. La cola CLH en Java es la variante CLH original de la cola, el hilo cambia del mecanismo de giro original a un mecanismo de bloqueo.

AQS se apoya en la cola de sincronización de CLH para completar la gestión del estado de sincronización:

  • Si el subproceso actual no puede obtener el estado de sincronización, AQS construirá el estado de espera del subproceso actual y otra información en un nodo (Nodo) y lo agregará a la cola de sincronización CLH, mientras bloquea el subproceso actual.
  • Cuando se libera el estado de sincronización, el primer nodo se despertará (bloqueo justo) para que pueda intentar obtener el estado de sincronización nuevamente.
  • Transfiera los nodos en la cola de condiciones a la cola de sincronización a través de signal o signalAll. (Convertida de cola condicional a cola síncrona)
    Insertar descripción de la imagen aquí

Cola de espera condicional

La cola de condiciones en AQS se guarda usando una lista unidireccional y se conecta usando nextWaiter:

  • Llame al método de espera para bloquear el hilo;
  • El hilo actual existe en el nodo principal de la cola de sincronización y llama al método de espera para bloquear (convertir de la cola de sincronización a la cola condicional)

Análisis del código fuente de ReentrantLock

ReentrantLock es una implementación de aplicación basada en el marco AQS . Es un método de sincronización para el acceso concurrente a subprocesos en JDK. Su función es similar a sincronizada , que es un bloqueo mutex que puede garantizar la seguridad de los subprocesos .
Uso básico de ReentrantLock

public class ReentrantLockTest {
    
    
    private final ReentrantLock lock = new ReentrantLock();
    // ...

    public void doSomething() {
    
    
        lock.lock();  // block until condition holds
        try {
    
    
            // ... method body
        } finally {
    
    
            lock.unlock();
        }
    }
}

Cuestiones a las que prestar atención al leer el código fuente

  • Cerraduras justas e injustas, cómo se implementan las cerraduras reentrantes
  • La esencia del diseño: cómo diseñar las operaciones de puesta en cola y retirada de cola en escenarios concurrentes
    • Implementación de lógica de bloqueo cuando los subprocesos compiten por bloqueos y no logran unirse a la cola
    • Implementación lógica de subprocesos de liberación de bloqueos que despiertan subprocesos bloqueados y los retiran de la cola para competir por los bloqueos.
      Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/beautybug1126/article/details/132003899
Recomendado
Clasificación