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:
- Uno para operaciones de solo lectura; y
- 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
- ReentrantReadWriteLock(): crea un nuevo ReentrantReadWriteLock con propiedades de ordenación predeterminadas (no justas).
- ReentrantReadWriteLock(boolean fair): crea un nuevo ReentrantReadWriteLock con la política de equidad dada.
Excepción lanzada:
- NullPointerException : si el bloqueo es nulo
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(); } } } } }
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