Clase ReentrantReadWriteLock en Java

La clase ReentrantReadWriteLock de Java es una implementación de ReadWriteLock, que también admite la funcionalidad ReentrantLock.

ReadWriteLock es un par de bloqueos asociados, uno para operaciones de solo lectura y otro para escritura. Mientras que ReentrantLock es un bloqueo de exclusión mutua reentrante con el mismo comportamiento que el bloqueo de monitor implícito al que se accede mediante métodos y declaraciones sincronizados, pero con algunas capacidades más ampliadas.

ReadWriteLock en Java

Incluso en una aplicación de subprocesos múltiples, pueden ocurrir varias lecturas simultáneamente para un recurso compartido. Solo cuando ocurren múltiples escrituras simultáneamente o se mezclan lectura y escritura, existe la posibilidad de escribir el valor incorrecto o leer el valor incorrecto.

ReadWriteLock en Java usa la misma idea para aumentar el rendimiento al tener un par de bloqueos separados. Un ReadWriteLock mantiene un par de bloqueos asociados:

  1. Uno para operaciones de solo lectura; y
  2. uno para escribir.

El bloqueo de lectura puede ser retenido simultáneamente por múltiples subprocesos de lectura, siempre que no haya escritores. El bloqueo de escritura es exclusivo.

Tener un par de bloqueos de lectura y escritura permite un mayor nivel de simultaneidad en el acceso a datos compartidos que el que permite un bloqueo de exclusión mutua. Aprovecha el hecho de que, si bien solo un único subproceso a la vez (un subproceso de escritura) puede modificar los datos compartidos, en muchos casos cualquier número de subprocesos puede leer los datos simultáneamente (por lo tanto, subprocesos de lectura).

Un bloqueo de lectura y escritura mejorará el rendimiento con respecto al uso de un bloqueo de exclusión mutua si la frecuencia de las lecturas es mayor que la de las escrituras, la duración de las operaciones de lectura es mayor que la duración de las escrituras. También depende de la disputa por los datos, es decir, la cantidad de subprocesos que intentarán leer o escribir los datos al mismo tiempo.

Vista del explorador de paquetes

• java.lang.Object
    • java.util.concurrent.locks.ReentrantReadWriteLock

Sintaxis:  Importando la clase 

public class ReentrantReadWriteLock
extends Object
implements ReadWriteLock, Serializable

Resumen del constructor

  1. ReentrantReadWriteLock(): crea un nuevo ReentrantReadWriteLock con propiedades de ordenación predeterminadas (no justas).
  2. ReentrantReadWriteLock(boolean fair): crea un nuevo ReentrantReadWriteLock con la política de equidad dada.

Excepción lanzada:

Implementación:

Vamos a haber creado tres implementaciones Runnable. Todos usan una variable de bloqueo ReentrantReadWriteLock. El bloqueo se crea utilizando el constructor ReentrantReadWriteLock(boolean fair), por lo que se le otorga una política de imparcialidad:

  • Leer obtiene el candado. Utiliza el método API readLock() de ReentrantReadWriteLock para obtener un ReadLock. Luego, adquiere el bloqueo de lectura, usando el método lock() de ReadLock. Mientras tiene el bloqueo, lee el valor de una variable de mensaje de string. Luego intenta liberar el bloqueo usando el método unlock() de ReadLock.
  • Tanto WriteA como WriteB también obtienen el bloqueo, usando el método writeLock(), que devuelve un WriteLock, y luego usando el método unlock() de WriteLock. Dado que tienen el bloqueo de escritura, ambos alteran el valor de la variable de mensaje de string. Luego, liberan el bloqueo de escritura usando el método unlock() de WriteLock.

Ejemplo

Java

// Java Program to Illustrate ReentrantReadWriteLock Class
 
// Importing ReentrantReadWriteLock
// fro java.util package
import java.util.concurrent.locks.ReentrantReadWriteLock;
 
// Class 1
// Main class
public class ReentrantReadWriteLockExample {
 
    private static final ReentrantReadWriteLock lock
        = new ReentrantReadWriteLock(true);
 
    // Initially the string contains only 1 character
    private static String message = "a";
 
    // Main driver method
    public static void main(String[] args)
        throws InterruptedException
    {
 
        // Creating threads
        Thread t1 = new Thread(new Read());
        Thread t2 = new Thread(new WriteA());
        Thread t3 = new Thread(new WriteB());
 
        // Starting threads with help of start() method
        t1.start();
        t2.start();
        t3.start();
        t1.join();
        t2.join();
        t3.join();
    }
 
    // Class 2
    // Helper class implementing Runnable interface
    static class Read implements Runnable {
 
        // run() method for thread
        public void run()
        {
 
            for (int i = 0; i <= 10; i++) {
                if (lock.isWriteLocked()) {
                    System.out.println(
                        "I'll take the lock from Write");
                }
 
                // operating lock()
                lock.readLock().lock();
 
                System.out.println(
                    "ReadThread "
                    + Thread.currentThread().getId()
                    + "Message is " + message);
                lock.readLock().unlock();
            }
        }
    }
 
    // Class 3
    // Helper class implementing Runnable interface
    static class WriteA implements Runnable {
 
        // run() method for thread
        public void run()
        {
 
            for (int i = 0; i <= 10; i++) {
 
                // Try block to check fr exceptions
                try {
                    lock.writeLock().lock();
                    message = message.concat("a");
                }
                finally {
                    lock.writeLock().unlock();
                }
            }
        }
    }
 
    // Class 4
    // Helper class implementing Runnable interface
    static class WriteB implements Runnable {
 
        // run() method for thread
        public void run()
        {
 
            for (int i = 0; i <= 10; i++) {
 
                // Try block to check for exceptions
                try {
                    lock.writeLock().lock();
                    message = message.concat("b");
                }
                finally {
                    lock.writeLock().unlock();
                }
            }
        }
    }
}
Producción

ReadThread 11 ---> Message is a
ReadThread 11 ---> Message is aba
ReadThread 11 ---> Message is ababa
ReadThread 11 ---> Message is abababa
ReadThread 11 ---> Message is ababababa
ReadThread 11 ---> Message is abababababa
ReadThread 11 ---> Message is ababababababa
ReadThread 11 ---> Message is abababababababa
ReadThread 11 ---> Message is ababababababababa
ReadThread 11 ---> Message is abababababababababa
ReadThread 11 ---> Message is ababababababababababa

Publicación traducida automáticamente

Artículo escrito por praveen13kulkarni y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *