Atomicidad - semáforos vs el tubo de JDK: ¿Por qué el tubo como una solución de bloqueo

principio de bloqueo - Semáforo contra el tubo: ¿Por qué el tubo de JDK

Programación concurrente catálogo de la serie de belleza: https://www.cnblogs.com/binarylei/p/9569428.html

El tubo y los semáforos pueden resolver los problemas de concurrencia, son equivalentes. Los llamados medios equivalentes se pueden realizar con el semáforo tubo, el semáforo también se puede utilizar para lograr el tubo. Sin embargo, el tubo está provisto sobre la base de la cantidad de estado de la señal de sincronización, más fácil de usar, lo que la tecnología Java se utiliza en el tubo. Parte de palabra clave sincronizada y wait (), notificar (), notifyAll () Estos tres métodos son del tubo.

1. Soluciones de programación concurrente - el tubo de semáforo vs

1.1 Conceptos relacionados

  1. Recursos Críticos : A pesar de que varios procesos pueden compartir una variedad de recursos en el sistema, pero muchos recursos sólo pueden ser utilizados como un proceso, que sólo permiten el uso de un proceso conocido como los recursos críticos de los recursos. Muchos dispositivos físicos son todos los recursos críticos, tales como impresoras. Además, hay muchas variables, por lo que los datos pueden ser compartidos por varios procesos, también son recursos críticos.
  2. sección crítica : el acceso a los recursos críticos, debe ser de manera mutuamente excluyentes, en cada proceso, el acceso a los recursos críticos de que el código se llama la zona crítica.
  3. Excluyentes entre sí : sólo un hilo puede acceder a la sección crítica.

1,2 vs el semáforo tubo

Este campo de tecnología de la programación concurrente se ha desarrollado desde hace medio siglo, la teoría y la compleja tecnología relacionada. ¿Existe una tecnología central que puede resolver fácilmente nuestro problema de concurrencia? De hecho, la implementación del mecanismo de bloqueo de dos maneras:

  • Semáforo (Semaphere) : Un método de coordinación para compartir recursos para facilitar el acceso al sistema operativo. Comparación y sincronización implementan en software, software de sincronización de sincronización es un mecanismo de consulta entre los hilos de la igualdad, no puede garantizar la atomicidad. El semáforo es gestionado por el sistema operativo, el estado del proceso es mayor que el sistema operativo para asegurar el semáforo atómica.
  • El tubo (Monitor) : semáforo resolver problemas operación de emparejamiento en la región crítica de la PV, la operación junto PV emparejado, la generación de un método de programación concurrente. Cuando dicha una condición mecanismo de sincronización variable.

Descripción: semáforos variable compartida S se encapsulan todas las operaciones sobre las variables compartidas S sólo son posibles a través de la PV, y esto no es orientado a objetos pensar no es igual que él? De hecho, la variable de paquete compartido es un medio común de programación concurrente.

En la cantidad de señal cuando la operación P no puede ser adquirido de bloqueo, el subproceso actual se sumará a la cola síncrona (SyncQueue) en. Cuando el resto de la rosca libera el bloqueo V, despertar subprocesos en espera de la cola de sincronización. Sin embargo, habrá muy complicado cuando varios subprocesos de emparejamiento de semáforos PV, de modo que el tubo se introduce en la cola de espera (el EsperarCola) concepto, encapsulados aún más estas operaciones complejas.

2. Semáforo (Semaphere)

2.1 Principio

Se compone de una variable de conformación de señal, y dos operaciones atómicas P y V. Operando garantía sistema atómico por la operación de conformación y la P V variable sólo a través de cambios operacionales.

  • Semáforo por uno y dos de formación en S PV variable de composición atómica.
  • P (Prolaag, tratar de reducir el holandés): magnitud de la señal menos 1, si el valor de la señal es menor que 0, entonces el recurso no es suficiente, se añade el proceso a la cola de espera.
  • V (Verhoog, aumentando holandés): magnitud de la señal más uno, si la magnitud de la señal es menor que o igual a 0, entonces el proceso de cola de allí, entonces espera el proceso para un despertador.

Descripción: variable compartida PV S solamente por la operación de los átomos de PV está garantizada por el sistema operativo. P bastante adquirir el bloqueo puede bloquear el hilo, y V es equivalente a cerraduras de liberación, sin bloquear el hilo. De acuerdo con el orden de sincronización cola de hilo despierta se puede dividir en dos tipos de justo e injusto.

Categoría del semáforo:

  • semáforo binario: el número de recursos es 0 o 1.
  • recursos de semáforo: el número de recursos para cualquiera que no sea negativo.

2.2 aplicación de código

private class Semaphore {
    private int sem;
    private WaitQueue q;

    void P() {
        sem--;
        if (sem < 0) {
            // add this thread t to q;
            block(t);
        }
    }

    void V() {
        sem++;
        if (sem <= 0) {
            // remove a thread t from q;
            wakeup(t);
        }
    }
}

Descripción: idea Semaphere es muy simple, se trata de una variable compartida S y la totalidad de su paquete unificado PV operativo juntos. De hecho, la variable de paquete compartido es un medio común de programación concurrente.

2.3 escenarios de uso

2.3.1 acceso exclusivo

Semaphore mutex = new Semaphore(1);
mutex.P();
// do something
mutex.V();

Lograr el área crítica de las consideraciones de acceso exclusivos: En primer lugar, el valor inicial del semáforo debe ser 1; la segunda es el uso de PV debe estar emparejado.

2.3.2 Acceso Condicional

Semaphore condition = new Semaphore(0);
// ThreadA,进行等待队列中
condition.P();

// ThreadB,唤醒等待线程 ThreadA
condition.V();

Condición para el acceso a la región crítica Nota: semáforo inicial debe ser cero, de modo que todo el hilo operaciones P llama no se puede obtener la cerradura, solamente esperar cola (cola de espera correspondiente al lado del tubo), cuando el hilo restante B se despertará las llamadas en espera hilo de operación V.

2.3.3 cola de bloqueo

El bloqueo de cola es un productor típico - modelo de consumo, en cualquier momento solamente un productor o de consumo hilos son hilos de acceder a la memoria intermedia. Y cuando el búfer está lleno, el hilo productor debe esperar, de lo contrario el hilo consumidor debe esperar.

  1. Cualquier tiempo de búfer de funcionamiento sólo un hilo: acceso exclusivo, el mutex binaria del semáforo, que es una señal inicial.
  2. Búfer vacío, los consumidores deben esperar a que el productor: condiciones de sincronismo, la cantidad de señal recursos NotEmpty, señal que es inicialmente cero.
  3. Cuando la memoria intermedia está llena, el productor debe esperar a que los consumidores: la sincronización de condición utilizando recursos semáforos notFull, su valor inicial de la señal n.
private class BoundedBuffer {
    private int n = 100;
    private Semaphore mutex = new Semaphore(1);
    private Semaphore notFull = new Semaphore(n);
    private Semaphore notEmpty = new Semaphore(0);

    public void product() throws InterruptedException {
        notFull.P();      // 缓冲区满时,生产者线程必须等待
        mutex.P();
        // ...
        mutex.V();
        notEmpty.V();      // 唤醒等待的消费者线程
    }

    public void consume() throws InterruptedException {
        notEmpty.P();      // 缓冲区空时,消费都线程等待
        mutex.P();
        // ...
        mutex.V();
        notFull.V();      // 唤醒等待的生产者线程
    }
}

Resumen: El uso directo de los semáforos, cuando una pluralidad de condiciones de sincronización de semáforos, el mal emparejamiento de PV difícil y fácil. Con el fin de resolver el difícil problema de la energía fotovoltaica emparejamiento, el debut tubo. El tubo es en realidad un paquete adicional de las condiciones de sincronización.

2. El tubo (Monitor)

Monitorear traducción literal es "Monitor", los sistemas operativos generales se traducen en "el tubo". El lado llamado tubo, se refiere al proceso de gestión de variables compartidas y operación variables compartidas, para que apoyen concurrente. Traducido en las áreas del lenguaje Java, que es las variables miembro y miembro del método de clase de gestión, por lo que esta clase es seguro para subprocesos. Así es como el tubo de tubo de él?

2.1 modelo MESA

En la historia del tubo, que ha aparecido en tres diferentes modelos de tubo, a saber: modelo Hasen, modelo Hoare y el modelo MESA. ¿Qué es ahora ampliamente utilizado modelo de MESA y la implementación de referencia de Java es el modelo MESA del tubo. Así que hoy nos centramos en qué modelo MESA.

En el campo de la programación concurrente, hay dos cuestiones fundamentales: uno es mutuamente excluyente, es decir, al mismo tiempo que permite sólo un hilo para acceder a recursos compartidos; el otro es síncrona, es decir, la forma de comunicarse entre hilos, la colaboración. Estas dos cuestiones son el tubo se puede resolver.

2,2 mutuamente excluyentes

En el tubo para lograr semáforo mutua exclusión y exactamente la misma, y ​​el funcionamiento del mismo son compartidos variable de paquete Unified juntos.

2.3 sincronización

En la cantidad de señalización para lograr el productor - códigos de patrones de consumo, con el fin de realizar la función de bloqueo de cola, es decir, a la espera - notificación (espera a notificar), excepto que un mutex, exclusión mutua, pero también requiere dos equipos completos y análisis de equipo fullBuffers y emptyBuffers recursos vacío de semáforos, para usar no sólo es complejo, sino también propenso a errores.

El tubo sobre la base de la cantidad de señal, y, además, aumentar la condición de sincronización, la operación descrita anteriormente complicado sellado.

JUC AQS también se basa en el tubo de lograr, se consigue una ReentrantLock basado cola de bloqueo, comparar la diferencia entre el foco y de semáforos. Hay bloqueando la cola en cola y quitar de la cola es de dos operaciones, estos dos métodos son para adquirir el modelo de proceso analogía tubería de entrada de exclusión mutua.

  1. Para la operación de puesta en cola, si la cola está llena, tiene que esperar hasta que la insatisfacción de cola que notFull.await ();.
  2. Para una operación de equipo, si la cola está vacía, tiene que esperar hasta que la cola no está vacía, que notEmpty.await ();.
  3. Si el equipo tiene éxito, entonces la cola no está vacía, es necesario notificar a las variables de condición: la cola no está vacía notEmpty cola de espera correspondiente.
  4. Si el equipo tiene éxito, se pondrá en cola insatisfecho, es necesario notificar a las variables de condición: cola insatisfecho notFull cola de espera correspondiente.
public class BlockedQueue<T> {
    final Lock lock = new ReentrantLock();
    // 条件变量:队列不满
    final Condition notFull = lock.newCondition();
    // 条件变量:队列不空
    final Condition notEmpty = lock.newCondition();

    // 入队
    void enq(T x) {
        lock.lock();
        try {
            while (队列已满) {
                // 等待队列不满
                notFull.await();
            }
            // add x to queue
            // 入队后,通知可出队
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    // 出队
    void deq() {
        lock.lock();
        try {
            while (队列已空) {
                // 等待队列不空
                notEmpty.await();
            }
            // remove the first element from queue
            // 出队后,通知可入队
            notFull.signal();
        } finally {
            lock.unlock();
        }
    }
}

Resumen: Para la realización del bloqueo de cola con un semáforo, no se siente a ser más simple. Antes notFull aquí es equivalente a fullBuffers, antes emptyBuffers equivalentes NotEmpty.

2,4 wait () la postura correcta

Para lado del tubo MESA, hay un paradigma de programación, es la necesidad de esperar la llamada () en un interior de bucle while. Esto es MESA tubo-específico. El llamado paradigma, es decir, aprendió las lecciones anteriores.

while (条件不满足) {
    wait();
}

A diferencia núcleo Hasen modelo, modelo Hoare MESA y el modelo es que cuando se cumplen las condiciones, cómo notificar el hilo pertinente. El tubo requiere el mismo tiempo que permite sólo un hilo de realizar, y que cuando la condición de funcionamiento de la rosca hilos T2 T1 esperar a encontrarse, T1 y T2 Quién puede hacerla cumplir?

  1. Hasen modelo que requiere notificar () en el código final, por lo que T2 T1 después de la notificación de finalización, T2 ha terminado, entonces T1 y luego ejecutar, por lo que podemos garantizar que sólo un hilo de ejecución.
  2. Hoare modelo dentro, aviso T2 Después de T1, T2 bloqueado, T1 ejecuta inmediatamente, y así sucesivamente T1 ejecutado, y después despierta T2, sino también para asegurar que sólo un hilo de ejecución. Sin embargo, en comparación con el modelo de Hasen, T2 más de una operación de bloqueo de despertador.
  3. Después de que el tubo interior MESA, T2 notificación de finalización T1, todavía entonces realizado T2, Tl no se realiza inmediatamente, simplemente a partir de la variable de entrada condición de espera en la cola de espera dentro de la cola. La ventaja de esto es para notificar () no coloque el código final, T2 no extra bloqueo de las operaciones de activación. Pero también hay un efecto secundario, es decir, cuando se ejecuta T1 nuevo, podría haber satisfecho las condiciones han sido satisfechas con el ahora , tenemos que comprobar la variable de condición de una manera cíclica.

Pensando 1: método wait (), en el modelo y el modelo Hasen Hoare no hay parámetros, y en el modelo de MESA que aumentan los parámetros de tiempo de espera, este parámetro se siente la necesidad de hacerlo?

Es necesario. Hasen está ejecutando la estela subir otro hilo, para garantizar la aplicación de la rosca. Hoare es interrumpe el hilo actual, otro hilo despierta, despierta para ir a jugar a la ejecución, sino también para asegurar la terminación. La MESA es una cola esperando para entrar, que no necesariamente tiene la oportunidad de realizar, lo que resulta en hambre.

Cuando 2,5 Notify () se puede usar

A no ser bien pensado, o tratar de utilizar notifyAll (), no utilice notificar ().

¿A qué hora se puede utilizar el Notify () hacer? Tenemos que cumplir las tres condiciones siguientes:

  1. Todos los subprocesos en espera tienen la misma condición de espera;
  2. Después de todo hilo la espera despierta, realizar la misma operación;
  3. Sólo hay que despertar a un hilo.

Ejemplos como el anterior bloqueo cola para "insatisfacción cola" con la variable de estado, su cola de bloqueo en el hilo está esperando "insatisfacción cola" con esta condición, que se refleja en el código es la siguiente tres líneas de código. Todos los subprocesos en espera, es la puesta en práctica de estas tres líneas de código, centrándose en la espera de condiciones en el interior son idénticos.

2.6 AQS y principios sincronizados

JUC AQS se implementa basándose en el tubo, el interior consta de dos colas, una cola síncrono, una cola es:

  1. Sincronización de cola: Cuando está ocupado el bloqueo, el hilo se añadirá a la cola de sincronización. Cuando se libera el bloqueo, que se despertará un hilo de la cola, se divide en dos tipos de justo e injusto.
  2. Lista de espera: Cuando se llama a lo esperan que el hilo se añadirá a la cola de espera. Cuando otro subproceso llama a notificar, será el hilo de la cola de espera a la cola de contención de sincronización, re-bloqueo.

Ver estructura de datos de tubo implementado ObjectMonitor también sincronizado basado en el núcleo. AQS y aplicaciones se sincronizan modelo MESA en el tubo de Java. Todo es de rutina a seguir.

referencia:

  1. √ semáforos y el tubo
  2. √ primitivas de sincronización OS
  3. Análisis en profundidad principio Sincronizado

Las intenciones de grabar un poco cada día. Tal vez el contenido no es importante, pero el hábito es muy importante!

Supongo que te gusta

Origin www.cnblogs.com/binarylei/p/12544002.html
Recomendado
Clasificación