Open In App

ReentrantReadWriteLock Class in Java

Last Updated : 26 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

ReentrantReadWriteLock class of Java is an implementation of ReadWriteLock, that also supports ReentrantLock functionality.

The ReadWriteLock is a pair of associated locks, one for read-only operations and one for writing. Whereas, the ReentrantLock is a re-entrant mutual exclusion Lock with the same behavior as the implicit monitor lock accessed using synchronized methods and statements, but with some more extended capabilities.

ReadWriteLock in Java

Even in a multi-threading application, multiple reads can occur simultaneously for a shared resource. It is only when multiple writes happen simultaneously or intermix of read and write that there is a chance of writing the wrong value or reading the wrong value.

ReadWriteLock in Java uses the same idea in order to boost the performance by having separate pair of locks. A ReadWriteLock maintains a pair of associated locks-

  1. One for read-only operations; and
  2. one for writing.

The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.

Having a pair of read-write lock allows for a greater level of concurrency in accessing shared data than that permitted by a mutual exclusion lock. It exploits the fact that while only a single thread at a time (a writer thread) can modify the shared data, in many cases any number of threads can concurrently read the data (hence reader threads).

A read-write lock will improve performance over the use of a mutual exclusion lock if the frequency of reads is more than writes, duration of the read operations is more than the duration of the writes. It also depends on the contention for the data – that is, the number of threads that will try to read or write the data at the same time.

Package explorer view

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

Syntax:  Importing the class 

public class ReentrantReadWriteLock
extends Object
implements ReadWriteLock, Serializable

Constructor Summary

  1. ReentrantReadWriteLock(): Creates a new ReentrantReadWriteLock with default (nonfair) ordering properties.
  2. ReentrantReadWriteLock(boolean fair): Creates a new ReentrantReadWriteLock with the given fairness policy.

Exception thrown:

Implementation:

We are going to have created three Runnable implementations. They all use a ReentrantReadWriteLock lock variable. The lock is created using the ReentrantReadWriteLock(boolean fair) constructor, so it is given a fairness policy:

  • Read gets the lock. It uses the readLock() API method of ReentrantReadWriteLock to get a ReadLock. Then, it acquires the read lock, using the lock() method of ReadLock. While having the lock, it reads the value of a String message variable. Then it attempts to release the lock, using the unlock() method of ReadLock.
  • Both WriteA and WriteB also get the lock, using writeLock() method, that returns a WriteLock, and then using unlock() method of WriteLock. Since having the write lock, they both alter the value of the String message variable. Then, they release the write lock, using the unlock() method of WriteLock.

Example

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();
                }
            }
        }
    }
}


Output

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


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads