Java sincronización uso mecanismo -ReentrantLock

concepto básico

ReentrantLock es de una fila a empezar JDK1.5 introdujo sus cabellos, que proporciona más flexibilidad que las características sincronizados pueden ser heredados, hay maneras en que puede, se puede tomar una variedad de variables de clase. Vamos a ver cómo ReentrantLock utilice el código siguiente:

public class ReentrantLockDemo {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        // 申请锁
        lock.lock();
        try {
            // 在此对共享数据进行访问
            // ...
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 总是在finally块中释放锁,以避免锁泄露
            lock.unlock();
        }
    }
}

Como puede verse en el código anterior, que era bastante simple, aquí a la nota que el mejor lugar es para liberar el bloqueo finally, a fin de no causar la liberación anormal de la cerradura no tuvo éxito, lo que resulta en pérdida de bloqueo.

método común

método explicación
bloquear() Adquirir un bloqueo
lockInterruptibly Si se interrumpe el flujo actual, entonces adquirir el bloqueo
trylock Tratar de adquirir el bloqueo, no hay otros hilos están compitiendo para adquirir el bloqueo y vuelve verdadero, falso si no, inmediatamente
desbloquear Liberar el bloqueo
newCondition Devuelve una nueva instancia Condición está ligada a esta instancia de bloqueo

CAS

CAS Nombre es comparar e intercambiar, comparar y de intercambio, es decir, la sincronización se logra mediante una instrucción atómica multi-hilo. Antes de modificar los datos en la memoria para empezar a leer el valor actual, el valor de la misma como se esperaba, cuando el real para modificar el tiempo, sería más que el valor real de la memoria es consistente con el valor esperado acaba de leer, si es coherente con el el éxito puede ser modificado, si no, la modificación falla (explicado en otros hilos durante la modificación ha sido modificado).
La siguiente figura muestra que no hay otras operaciones de rosca con un valor de la memoria durante el funcionamiento:
Aquí Insertar imagen Descripción
La siguiente figura muestra los otras operaciones de rosca con un valor de la memoria durante la operación de:
Aquí Insertar imagen Descripción

AQS

AQS (AbstractQueuedSynchronizer) cola sincronizador es decir, el bastidor de base se construye que cerraduras u otro componente de sincronización, que es el núcleo JUC y contrayendo el componente base. AQS incluye principalmente los siguientes:

  • Estado variable de estado: AQS por un valor entero para identificar el bloqueo no ha sido ocupado.
  • Sincronización de cola: cola de sincronización interna AQS mantiene una estructura de lista enlazada, cuando el bloqueo de rosca competencia falla, se coloca en la cola de sincronización.
  • colas Condición: cola de espera es para la implementación / notificación (similar a la espera sincronizada / notificar).

principio de funcionamiento síncrono de colas

Aquí Insertar imagen Descripción

  • Cuando sólo un hilo de ejecución, el hilo se envasa Node, adquirir el bloqueo y se inserta en la lista para la ejecución de la cabeza.
  • Múltiples hilos que compiten simultáneamente cerradura, la cerradura no se adquiere, se envasaron en un nodo, y a su vez insertado en el extremo bloqueado de la cola.
  • subproceso de ejecución posee actualmente el bloqueo después de que se libere el bloqueo, y despertar un hilo detrás de él, se volvió a despertar la contención de bloqueo de rosca, después de obtener la ejecución, después de la implementación de una similar, pero también despertar una larga hilo de la cerradura y de la espalda.

principio de funcionamiento cola de condición

Aquí Insertar imagen Descripción

  • Cuando el hilo que tiene el bloqueo, de manera que el método llama hilo Condition.await entra en un estado de espera, se inserta primero en la cola correspondiente Condición (Condición vías lista enlazada cola es).
  • Condición inserta en la cola que va a liberar el bloqueo actual, y se despierta después de bloquear una cola de hilo, que elimina el bloqueo de sí mismo de la cola.
  • Si la llamada al método Condition.signal, despertará un hilo esperando en la condición de ser despertado hilo se inserta en la cola de la cola de bloqueo, y las condiciones de eliminar de la cola.

principio interno ReentrantLock

Buscamos ReentrantLock seguimiento del código fuente, entramos en que queda inmovilizado método:

  // ReentrantLock.lock()
  public void lock() {
  	  // 这个sync,是我们new ReentrantLock()时初始化的
      sync.lock();
  }

  //  无参构造函数
  public ReentrantLock() {
  	  // 默认初始化一个非公平锁
      sync = new NonfairSync();
  }

Aquí primero introducimos bloqueo bloqueo justo e injusto.

cerraduras justas

medios de bloqueo Fair que todos los hilos de la solicitud de bloqueo en el orden realizarán de forma secuencial (por ejemplo .: Cuando una nueva solicitud de hilo, no se encuentran otros hilos de bloqueo colas de colas, que se inserta directamente en la cola de la cola de bloqueo cola).
Cuando creamos objetos ReentrantLock, pasando un verdadero argumento se crea que es justo cerraduras:

ReentrantLock lock = new ReentrantLock(true);

bloqueo injusto

bloqueo injusto es tener cualquier nuevos temas intentar adquirir el bloqueo, hay una gran oportunidad de llegar directamente a las cerraduras (por ejemplo: una nueva solicitud de hilo, independientemente de su lista de bloqueo no tienen otro hilo en la cola, para competir directamente bloqueo, Si la competencia es en la ejecución directa de éxito).

ReentrantLock Al crear un nuevo, por defecto es injusto bloqueo, nos queda inmovilizado en su código NonfairSync injusta:

  static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        // 获取锁方法
        final void lock() {
            if (compareAndSetState(0, 1))
                // 获取到了锁设置一下当前线程是自身
                setExclusiveOwnerThread(Thread.currentThread());
            else
            	// 获取锁失败,则进入阻塞队列
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

Introduzca método compareAndSetState:

  protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

Hemos dicho antes, AQS es un estado por un valor entero (por defecto es 0) para identificar el bloqueo no ha sido ocupado, aquí es el camino por el CAS, el estado de 0 a 1, si la modificación es exitosa explicó bloqueo adquirido con éxito, Si la modificación no explicación no pudo adquirir el bloqueo. La modificación no pudo entrar en el método de adquisición:

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
        	// 加入阻塞队列
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

Como puede verse, no competir después de la cerradura, que se añadirá a la cola de bloqueo. Nosotros no llegamos a la parte inferior de la cara posterior.

Liberadas nueve artículos originales · ganado elogios 3 · Vistas 2424

Supongo que te gusta

Origin blog.csdn.net/ym572170/article/details/104802663
Recomendado
Clasificación