Bloqueo de sincronización de subprocesos múltiples Bloqueo de bloqueo

Bloqueo de sincronización de subprocesos múltiples-Bloqueo de bloqueo-ReentrantLock

El mecanismo de sincronización de subprocesos Sincronizar bloqueo se mencionó anteriormente.De hecho, también hay un bloqueo JUC Lock que también puede lograr la sincronización de subprocesos. Además, la clase de implementación de Lock ReentrantLock es más flexible y más rica que Synchronize, y es más adecuada para su uso en la mayoría de los escenarios.
Comparemos brevemente ReentrantLock y Synchronize.

  1. El bloqueo de sincronización es un bloqueo exclusivo. El bloqueo y la liberación de los bloqueos son automáticos, siempre que se agregue la palabra clave sincronizar o un bloque de código. Es muy simple de usar, pero menos flexible. ReentrantLock también es un bloqueo exclusivo, pero requiere bloqueo manual (bloqueo, etc.) y desbloqueo (desbloqueo). Es relativamente complicado de usar, pero es flexible, y ReentrantLock proporciona una gran cantidad de métodos.
  2. Synchronsize y ReentrantLock son bloqueos reentrantes (los bloqueos se pueden usar varias veces: por ejemplo, el método A usa un bloqueo, pero en realidad llama a B, pero B también usa un bloqueo, lo que significa que no es necesario volver a adquirir el bloqueo al llamar B). Pero todos deben liberar el bloqueo para permitir que otros hilos lo obtengan.
  3. Una vez que Synchronize no puede obtener el bloqueo y se genera un estado de espera de interbloqueo, no se puede interrumpir el correspondiente y ReentrantLock proporciona el bloqueo de orden medio correspondiente.
  4. Lo más importante es que ReentrantLock también puede implementar un mecanismo de bloqueo justo. ¿Qué es fair lock? Es decir, el hilo que haya esperado más tiempo en el candado tendrá derecho a usar el candado. El entendimiento popular es que quien haya estado en la cola más larga adquirirá el candado primero.

A diferencia de Synchronize, ReentrantLock proporciona múltiples bloqueos que pueden manejar problemas de sincronización de subprocesos de acuerdo con diferentes necesidades. A continuación, nos centramos en el bloqueo ReentrantLock. Para la introducción de Synchronize, consulte el blog anterior Thread Insecurity + Thread Deadlock + Synchronization .

ReentrantLock es una clase del paquete JUC (java.util.concurrent.locks.ReentrantLock), que implementa la interfaz Lock.
Inserte la descripción de la imagen aquí
Los bloqueos de liberación de ReentrantLock son todos el mismo método de desbloqueo, a continuación se examinan principalmente los diferentes bloqueos de ReentrantLock.
Cuando no se implementa la sincronización de subprocesos, no hay efecto de bloqueo:

public class ReenTrantLockThread {
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        new Thread(threadTest,"小明").start();
        new Thread(threadTest,"小王").start();
    }
}

class ThreadTest implements Runnable{
    final Lock lock = new ReentrantLock();
    @Override
    public void run() {
        study();
    }

    public void study(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":我正在学习");
        }
    }
}

Resultado:
Inserte la descripción de la imagen aquí
Xiao Ming y Xiao Wang estaban locos y aprendieron mediante la programación de la CPU. Después de agregar el bloqueo, deje que una persona termine de aprender y luego el siguiente hilo tomará el bloqueo para aprender (tenga en cuenta que el siguiente hilo no es necesariamente otra persona, está programado por la CPU)

(1) Bloqueo () Este bloqueo es un bloqueo común y de uso común, similar al bloqueo Sincronizar. Una vez obtenido el bloqueo, debe esperar a que se libere el bloqueo antes de poder continuar reteniendo el bloqueo; de lo contrario, se producirá un interbloqueo de hilo. ocurren, por lo que el bloqueo debe liberarse después del final de su uso.
Nota: Para evitar que se suelte el bloqueo, por lo general, ponga el contenido del bloqueo en el intento y luego suelte el bloqueo en el final, para asegurarse de que se libere el bloqueo.

    public void study(){
        lock.lock();
        try {    /
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+":我正在学习");
            }
        }catch (Exception e){
        }finally {
            lock.unlock()
        }
    }  

Resultado: ¡¡¡Deje que una persona termine de aprender y luego aprenda con el candado en el siguiente hilo !!!
Inserte la descripción de la imagen aquí

(2) tryLock () lock. Yo lo llamo try lock. Se usa para intentar adquirir el candado. Si se puede adquirir, entonces el candado se puede ocupar y usar. Si no está disponible, también podemos manejar otros cosas. Tiene un valor de retorno, el tipo es booleano, si obtiene el bloqueo, devuelve verdadero, y si no puede obtenerlo, devuelve falso, por lo que inmediatamente devolverá un valor sin importar qué.

public void study(){
        boolean flag = lock.tryLock();
        if(flag){
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName()+":我正在学习");
                }
            }catch (Exception e){

            }finally {
                lock.unlock();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+":我没拿到锁,那我去看电视了");
        }
    }

Resultado:
Inserte la descripción de la imagen aquí
(3) tryLock (tiempo de espera largo, unidad TimeUnit), el uso es el mismo que tryLock, la diferencia es que puede especificar el tiempo de espera, es decir, bloquearme y mantener el bloqueo, si el bloqueo no se obtiene después el tiempo especificado, devolveré falso, tiempo Antes de eso, seguí esperando a que se liberara el bloqueo.

public void study() throws InterruptedException {
        boolean flag = lock.tryLock(5000,TimeUnit.MILLISECONDS); // 等待5秒钟拿不到锁就返回false
        if(flag){
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName()+":我正在学习");
                }
            }catch (Exception e){

            }finally {
                lock.unlock();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+":我没拿到锁,那我去看电视了");
        }
    }

Resultado: el bloqueo se obtuvo con éxito en 5 segundos.
Inserte la descripción de la imagen aquí
Agregamos un sueño al hilo, dejamos que el hilo descanse por más de 5 segundos,
Inserte la descripción de la imagen aquí
(4) lockInterruptiblemente () bloqueo de interrupción, use este bloqueo para interrumpir activamente el hilo usando Thread.interrupt (). La premisa es que este hilo usa un candado y no se puede usar sin un candado. Esto no es fácil de demostrar, el uso es el siguiente:
Inserte la descripción de la imagen aquí
Luego hable sobre el mecanismo de bloqueo especial de ReentrantLock, el bloqueo justo y el bloqueo injusto.
Al igual que el significado literal,
fair lock significa que el hilo que se pone en cola durante mucho tiempo permitirá que quien tenga la ventaja de programar.
El bloqueo injusto significa que no importa cuándo los subprocesos comiencen a hacer cola, dejo que la CPU mire la programación del estado de ánimo.
El método de uso es muy simple, solo necesita agregar el parámetro verdadero (justo) o falso (injusto) al inicializar el bloqueo. El valor predeterminado es
el bloqueo justo falso :

final Lock lock = new ReentrantLock(true);
public void study() throws InterruptedException {
        for (int i = 0; i <2 ; i++) {
            try {
                lock.lock(); // 等待5秒钟拿不到锁就返回false
                System.out.println(Thread.currentThread().getName()+":我正在学习");
                //Thread.sleep(2000);
            }catch (Exception e){

            }finally {
                lock.unlock();
            }
        }
    }

Resultado: no apriete, todos tienen una participación.
Inserte la descripción de la imagen aquí
Bloqueo injusto:

    final Lock lock = new ReentrantLock(false);
    public void study() throws InterruptedException {
        for (int i = 0; i <2 ; i++) {
            try {
                lock.lock(); // 等待5秒钟拿不到锁就返回false
                System.out.println(Thread.currentThread().getName()+":我正在学习");
                //Thread.sleep(2000);
            }catch (Exception e){

            }finally {
                lock.unlock();
            }
        }
    }

Resultado: la siguiente
Inserte la descripción de la imagen aquípresentación de la película: bloqueo de lectura y escritura.

Supongo que te gusta

Origin blog.csdn.net/qq_31142237/article/details/114648496
Recomendado
Clasificación